Rationale and
Objectives
This document details the modeling workflow implemented for
estimating dissolved and equilibrium N2O concentrations and saturation
ratios using the 2017 Nation Lakes Assessment (NLA) survey data. The NLA
sampling sites were distributed among the target population of US lakes
(in the lower 48 states) according to a probabilistic survey design with
samples stratified among categories of lake surface area, WSA9
ecoregion, and US state (excluding AK and HI). Due to the stratification
scheme, some types of lakes in the sample population were intentionally
over-represented (e.g., large lakes) and some were under-represented
(e.g., small lakes) relative to the target population. Due to the
unequal probability design, inferences from the sample had to be
adjusted for inferences on the broader populations of interest (e.g,
National-, state-, ecoregion-, and size class-specific estimates).
The concept of the “complete data likelihood” is useful for
conceptualizing biases arising from sampling design (Zachmann et al. 2022; Gelman et al. 2014
Ch. 8; Link and
Barker 2010). For the NLA survey data, the population of US
lakes in the lower 48 states larger than 4 hectares was considered the
complete data and the probabilistic samples were considered a subset of
that complete data. The portion of US lakes not included in the sample
were considered “missing” from the complete data not at random,
but conditional on the pre-specified design (stratification) variables.
This non-random missingness was not ignorable for the purpose of making
inferences from the sample to the target population. In a model-based
framework, however, including the design parameters as predictors in a
regression model is one way to adjust for the missingness. For a
thorough and recent treatment of this concept in the context of national
surveys of environmental resources, refer to (Zachmann et al.
2022). This concept is a key motivator for the increasingly
popular mulitilevel regression with poststratification (MRP) approach to
model-based inference [Gelman et al. (2014);
Gelmant_etal_2020 Ch. 17].
The following workflow illustrates our model-based approach, based
largely on the logic of MRP, but with an elaboration on the
poststratification step to enable eventual estimates of total gas flux
at the population level, which required scaling up from lake-level
estimates. The typical MRP process is carried out in two steps. The
first step is to fit regression models for the response variables of
interest (e.g., dissolved N2O, equilibrium N2O) conditional on the
survey design variables ┼(i.e., ecoregion, state, lake size). The second
step is post-stratfication, wherein the posterior parameter estimates
from the regression model for the sample population are weighted based
on their known or assumed distribution in the population of interest
[i.e., post-stratification table; Gelman, Hill,
and Vehtari (2020) Ch. 17]. The poststratification
table in our case, for example, would be a population summary of lakes
among the design variables: ecoregion, state, and size category.
However, because we eventually needed lake-level estmates, instead of
predicting to a postratification table, we predicted to each individual
lake in the population of interest. This meant predicting to the full
target population of 465,897 natural and man made US lakes larger than 4
hectares in the lower 48 states. These predictions were assumed relevant
to average conditions during the “index period” for each lake in 2017.
Details about the sampling frame as well as the target population are
further clarified in the workbook below with data summaries and
code.
For the regressions, we used multilevel models fit in a fully
Bayesian fashion Multilevel models are thought to work well in this
context because they provide regularized estimates along the design
groupings, which can improve out-of-sample inferences (McElreath 2020). Inferences for lake
types that may be missing from the sample, but are part of the
population of interest are also straightforward using this approach
(Gelman, Hill, and Vehtari 2020 Ch. 17; McElreath
2020). More information these models, their specific
parameters, R code, fit evaluations, and resulting inferences are
presented in this document.
The overriding objective of the modeling effort was to provide
population level estimates for (1) dissolved and equilibrium N2O
concentrations; (2) the N2O saturation ratio (i.e., dissolved
N2O/equilibrium N2O); and (3) the proportion of under-saturated water
bodies (i.e., saturation ratio < 1). The estimates would also be used
to later estimate the total flux of N2O gas attributable to the target
population of lakes over the index period. The saturation ratio
estimates were calculated as a derived quantity based on the ratio of
modeled dissolved to equilibrium N2O. Because dissolved and equilibrium
N2O were observed on the same sample units (lake sites), we developed
models for estimating their joint distribution. The response variable in
the models was, therefore, multivariate to account for potential
statistical dependencies between dissolved and equilibrium N2O due to,
for example, common dependencies on geography. Although point
predictions of the mean marginal probabilities from separate models
could be comparable, a joint model allowing correlated observation-level
errors (i.e., residuals) was expected to better capture uncertainty and
potentially improve out-of-sample predictions, should the variables be
conditionally correlated (Warton et al.
2015; Poggiato et al. 2021). All of the models
fit were constructed using the brms package (Bürkner 2017) in R (R
Core Team 2021) as an interface to Stan, a software package
for fitting fully Bayesian models via Hamiltonian Monte Carlo [HMC;
Team (2018b); Team (2018c); Team (2018a)].
Data
As explained in a previous data munging document document (https://github.com/USEPA/DissolvedGasNla/blob/master/scripts/dgIndicatorAnalysis.html),
duplicate dissolved gas samples were collected at a depth of ~0.1m at
designated index sites distributed across 1091 lakes nationwide, of
which 95 were sampled twice as repeat visits. This randomly selected
subset of revisit sites was used as a test set for assessing model fit
and out-of-sample performance.
Gas samples were analyzed via gas chromotography and concentrations
were recorded to the nearest 0.001 nmol/L. The samples were collected
under a stratified, unequal probability design and each gas observation
was indexed to an individual lake selected with unequal probability from
5 different lake size categories, \(j \in
j=1,...,J = 5\), according to surface area (ha), and from within
a state, \(k \in k=1,...,K = 48\),
situated within an aggregated, WSA9 or Omernik ecoregion, \(l \in l=1,...,L = 9\). All 9 WSA9
ecoregions were represented in the sample, including Xeric (XER),
Western Mountain (WMT), Northern Plains (NPL), Southern Plains (SPL),
Temperate Plains (TPL), Coastal Plains (CPL), Upper Midwest (UMW),
Northern Appalachian (NAP), and Southern Appalachian (SAP) regions. As
shown below, the data from the initial and revisit samples were
separately compiled into data frame objects in \(\textbf{R}\), with \(n=984\) and \(n=95\) rows, respectively, of gas
observations indexed to the survey design variables and several
potentially relevant covariates.
Import
The gas data and covariates were previously described and munged at
https://github.com/USEPA/DissolvedGasNla/blob/master/scripts/dataMunge.html.
That dataset was imported below.
load( file = paste0( localPath,
"/Environmental Protection Agency (EPA)/",
"ORD NLA17 Dissolved Gas - Documents/",
"inputData/dg.2021-02-01.RData")
)
save(dg, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/dg.rda")
From the imported dataset, a new data frame for modeling was
constructed from the original file including only the variables of
interest: (1) the N2O gas observations; (2) the survey design variables
indexed to those observations; and (3) additional covariates considered
potentially useful for improving the fit of the model. The data frame
below excluded the second-visit observations, which would later be used
for model checking. Some variables from the imported data were renamed
for convenience. In addition, the NO3 covariate was rounded according to
the documented measurement precision. An alternative version of the NO3
covariate was also created in this step by log-transforming and
re-coding it as an ordered factor with five levels at hand-drawn cut
points. The left-most cut point separated observations below the
detection limit from the completely observed samples. The remaining cut
points in the positive direction were drawn at approximately equal
distances along the log scale. Finally, it should be noted that one lake
that was sampled was missing information on the N2O gas measurements and
it was removed from the data frame.
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/dg.rda")
dg %>%
filter(!is.na(dissolved.n2o.nmol)) %>% # 1 obs with missing measurement
nrow() # number of observations before filtering
[1] 1185
df_model <- dg %>%
filter(!is.na(dissolved.n2o.nmol)) %>%
filter(sitetype == "PROB") %>% # probability samples only
filter(visit.no == 1) %>%
mutate(n2o = round(dissolved.n2o.nmol, 2),
n2o_eq = round(sat.n2o.nmol, 2),
n2o_sat = n2o.sat.ratio,
n2o_em = e.n2o.nmol.d,
n2o_flux = f.n2o.m.d,
WSA9 = factor(ag.eco9),
state = factor(state.abb[match(state.nm, state.name)]),
area_ha = area.ha,
log_area = log(area_ha),
chla = chla.result,
log_chla = log(chla),
elev = elevation,
log_elev = log(elev + 1),
do_surf = o2.surf,
log_do = log(do_surf),
bf_max = max.bf,
sqrt_bf = sqrt(bf_max),
size_cat = recode(area.cat6,
"(1,4]" = "min_4" ,
"(10,20]" = "10_20",
"(20,50]" = "20_50",
"(4,10]" = "4_10",
">50" = "50_max")) %>%
mutate(size_cat = factor(size_cat,
levels = c("min_4", "4_10", "10_20", "20_50", "50_max"),
ordered = TRUE)) %>%
mutate(no3 = ifelse(nitrate.n.result <= 0.0005, 0.0005, round(nitrate.n.result, 4))) %>%# 1/2 mdl 0.01
mutate(no3_cat = cut(log(no3), # convert no3 to ordered factor with 5 levels
breaks = c(-Inf, -7.5, -5.5, -3.5, -1.5, Inf),
labels =seq(1, 5, 1))) %>%
mutate(no3_cat = factor(no3_cat,
levels = seq(1, 5, 1),
ordered = TRUE)) %>%
mutate(date = as.Date(date.col)) %>%
mutate(jdate = as.numeric(format(date, "%j"))) %>%
mutate(lat = map.lat.dd,
lon = map.lon.dd) %>% # longitude
mutate(surftemp = surftemp,
log_surftemp = log(surftemp)) %>%
select(WSA9,
state,
size_cat,
site.id,
lat,
lon,
date,
jdate,
surftemp,
log_surftemp,
area_ha,
log_area,
elev,
log_elev,
chla,
log_chla,
do_surf,
log_do,
bf_max,
sqrt_bf,
n2o,
n2o_eq,
no3,
no3_cat
)
save(df_model, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/df_model.rda")
nrow(df_model) # number of obs after filtering
[1] 984
print(df_model)
A second dataframe, including only the second visit observations, was
constructed below. These data were later used as a “test set” to assess
the out-of-sample fit of the model developed on the first-visit or
training data.
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/dg.rda")
# number of observations before filtering probability samples
dg %>%
filter(!is.na(dissolved.n2o.nmol)) %>% # remove obs with missing response measurements
nrow()
[1] 1185
df_test <- dg %>%
filter(!is.na(dissolved.n2o.nmol)) %>%
filter(sitetype == "PROB") %>% # probability samples only
filter(visit.no == 2) %>%
mutate(n2o = round(dissolved.n2o.nmol, 2),
n2o_eq = round(sat.n2o.nmol, 2),
n2o_sat = n2o.sat.ratio,
n2o_em = e.n2o.nmol.d,
n2o_flux = f.n2o.m.d,
WSA9 = factor(ag.eco9),
state = factor(state.abb[match(state.nm, state.name)]),
area_ha = area.ha,
log_area = log(area_ha),
chla = chla.result,
log_chla = log(chla),
elev = elevation,
log_elev = log(elev + 1),
do_surf = o2.surf,
log_do = log(do_surf),
bf_max = max.bf,
sqrt_bf = sqrt(bf_max),
size_cat = recode(area.cat6,
"(1,4]" = "min_4" ,
"(10,20]" = "10_20",
"(20,50]" = "20_50",
"(4,10]" = "4_10",
">50" = "50_max")) %>%
mutate(size_cat = factor(size_cat,
levels = c("min_4", "4_10", "10_20", "20_50", "50_max"),
ordered = TRUE)) %>%
mutate(no3 = ifelse(nitrate.n.result <= 0.0005, 0.0005, round(nitrate.n.result, 4))) %>%# 1/2 mdl 0.01
mutate(no3_cat = cut(log(no3), # convert no3 to ordered factor with 5 levels
breaks = c(-Inf, -7.5, -5.5, -3.5, -1.5, Inf),
labels =seq(1, 5, 1))) %>%
mutate(no3_cat = factor(no3_cat,
levels = seq(1, 5, 1),
ordered = TRUE)) %>%
mutate(date = as.Date(date.col)) %>%
mutate(jdate = as.numeric(format(date, "%j"))) %>%
mutate(lat = map.lat.dd,
lon = map.lon.dd) %>% # longitude
mutate(surftemp = surftemp,
log_surftemp = log(surftemp)) %>%
select(WSA9,
state,
size_cat,
site.id,
lat,
lon,
date,
jdate,
surftemp,
log_surftemp,
area_ha,
log_area,
elev,
log_elev,
chla,
log_chla,
do_surf,
log_do,
bf_max,
sqrt_bf,
n2o,
n2o_eq,
no3,
no3_cat
)
save(df_test, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/df_test.rda")
nrow(df_test) # number of obs after filtering for probability samples, first visits, and removing one site missing ecoregion (WSA9) info.
[1] 95
print(df_test)
Target
population
Below. the NLA sampling frame was imported and then filtered to
include only the target population or sampling frame for this
project.
df_pop <- read.csv(file = paste0(localPath,
"/Environmental Protection Agency (EPA)/",
"ORD NLA17 Dissolved Gas - Documents/",
"inputData/NLA_Sample_Frame.csv"), header = T)
sframe <- df_pop %>%
filter(nla17_sf != "Exclude2017") %>%
filter(nla17_sf != "Exclude2017_Include2017NH") %>%
filter(state != "DC") %>%
filter(state != "HI") %>%
droplevels() %>%
mutate(WSA9 = factor(ag_eco9),
WSA9 = forcats::fct_drop(WSA9), # remove NA level
state = factor(state),
size_cat = factor(area_cat6),
lat = lat_dd83,
lon = lon_dd83,
log_area = log(area_ha),
elev = elevation,
log_elev = ifelse(elev <= 0, 0, elev), # assumed elev < 0 to be elev = 0
log_elev = log(log_elev + 1)
) %>%
mutate(size_cat = recode(size_cat,
"(1,4]" = "min_4" ,
"(10,20]" = "10_20",
"(20,50]" = "20_50",
"(4,10]" = "4_10",
">50" = "50_max")) %>%
mutate(size_cat = factor(size_cat,
levels = c("min_4", "4_10", "10_20", "20_50", "50_max"),
ordered = TRUE)) %>%
select(WSA9, state, size_cat, lat, lon, area_ha, log_area, elev, log_elev)
rm(df_pop)
save(sframe, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/sframe.rda")
print(sframe)
The resulting target population above included a total of 465,897
waterbodies.
Cross tabulations below describe the structure of the target
population with respect to the design variables. The cross-tabulation
makes it clear that each ecoregion does not contain each state.
Therefore, in the statistical sense, states were nested in
ecoregions.
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/sframe.rda")
sframe %>%
group_by(WSA9, state) %>%
summarise(n = n(), .groups = "drop") %>%
spread(state, n) %>%
print()
Likewise, lake size category was nested in state (which was nested in
ecoregion). That is, not every ecoregion:state in the population of
interest contained every size category (below).
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/sframe.rda")
sframe %>%
group_by(WSA9, state, size_cat) %>%
summarise(n = n(), .groups = "drop") %>%
spread(size_cat, n) %>%
print()
Below, the sampling frame was selected down to create a
post-stratification table. Some of the variables were renamed to match
the naming conventions used in the observational data above. There were
536 types of lakes in the population of interest with respect to the
sampling design. The counts of those lake types (n_lakes) and their
proportions relative to the total population of lakes in the sampling
frame (prop_cell) are indicated below.
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/sframe.rda")
pframe <- sframe %>%
mutate(obs = 1) %>%
group_by(WSA9, state, size_cat) %>%
summarise(n_lakes = sum(obs), .groups = "drop") %>%
ungroup() %>%
mutate(prop_cell = n_lakes/sum(n_lakes)) %>%
mutate(type = "population")
save(pframe, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/pframe.rda")
print(pframe)
Sample
vs. population
Below, the lake distributions in the population of interest were
compared to the proportions in the observed sample. There were 352 lake
types in the sample compared to the 536 in the population of of
interest. In total, there were 984 observations distributed across these
352 lake types in the sample; and the number of samples was not
distributed evenly across the types. Some cells were represented by as
few as 1 lake. In total, 536-352 = 184 lake types in the population of
interest were not represented in the sample.
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/df_model.rda")
samp_props <- df_model %>%
mutate(obs = 1) %>%
group_by(WSA9, state, size_cat) %>%
summarize(n_lakes = sum(obs), .groups = "drop") %>%
ungroup() %>%
mutate(prop_cell = round(n_lakes / sum(n_lakes), 7)) %>%
mutate(type = "sample")
save(samp_props, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/samp_props.rda")
print(samp_props)
Below, a graphical comparison was constructed to depict the
distribution of cells in the population of interest versus
those in the sample.

Another comparison between population and sample was constructed
below by ecoregion. The samples were not balanced across ecoregions.
Lakes in the Coastal Plains (CPL) ecoregion, for example, were clearly
undersampled relative to their proportion of the population.
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/pframe.rda")
pframe_eco <- pframe %>%
group_by(WSA9) %>%
summarise(n_lakes = sum(n_lakes)) %>%
ungroup() %>%
mutate(prop_cell = round(n_lakes/sum(n_lakes), 7)) %>%
ungroup() %>%
mutate(type = 'population')
save(pframe_eco, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/pframe_eco.rda")
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/samp_props.rda")
samp_props_eco <- samp_props %>%
group_by(WSA9) %>%
summarise(n_lakes = sum(n_lakes)) %>%
ungroup() %>%
mutate(prop_cell = round(n_lakes/sum(n_lakes), 7)) %>%
ungroup() %>%
mutate(type = 'sample')
save(samp_props_eco, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/samp_props_eco.rda")

A similar comparison by state was constructed below.
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/pframe.rda")
pframe_state <- pframe %>%
group_by(state) %>%
summarise(n_lakes = sum(n_lakes)) %>%
ungroup() %>%
mutate(prop_cell = round(n_lakes/sum(n_lakes), 7)) %>%
ungroup() %>%
mutate(type = 'population')
save(pframe_state, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/pframe_state.rda")
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/samp_props.rda")
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/samp_props.rda")
samp_props_state <- samp_props %>%
group_by(state) %>%
summarise(n_lakes = sum(n_lakes)) %>%
ungroup() %>%
mutate(prop_cell = round(n_lakes/sum(n_lakes), 7)) %>%
ungroup() %>%
mutate(type = 'sample')
save(samp_props_state, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/samp_props_state.rda")

Finally, a comparison by lake size category is shown below. Note that
small lakes were under-sampled relative to larger lakes by design.
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/pframe.rda")
pframe_size <- pframe %>%
group_by(size_cat) %>%
summarise(n_lakes = sum(n_lakes)) %>%
ungroup() %>%
mutate(prop_cell = round(n_lakes/sum(n_lakes), 7)) %>%
ungroup() %>%
mutate(type = 'population')
save(pframe_size, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/pframe_size.rda")
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/samp_props.rda")
samp_props_size <- samp_props %>%
group_by(size_cat) %>%
summarise(n_lakes = sum(n_lakes)) %>%
ungroup() %>%
mutate(prop_cell = round(n_lakes/sum(n_lakes), 7)) %>%
ungroup() %>%
mutate(type = 'sample')
save(samp_props_size, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/samp_props_size.rda")

Sample-based
estimates
The overall mean and standard deviation for N2O in the sample:
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/df_model.rda")
df_model %>%
summarise(mean = mean(n2o),
sd = sd(n2o)) %>%
print()
The same summary for equilibrium N2O:
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/df_model.rda")
df_model %>%
summarise(mean = mean(n2o_eq),
sd = sd(n2o_eq)) %>%
print()
The saturation ratio (i.e., N2O / N2O-eq):
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/df_model.rda")
df_model %>%
summarise(mean = mean(n2o / n2o_eq),
sd = sd(n2o / n2o_eq)) %>%
print()
Finally, roughly 67% of lakes in the sample were undersaturated
(i.e., saturation ratio < 1):
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/df_model.rda")
df_model %>%
summarise(prop_undersat = sum((n2o / n2o_eq) < 1) / 984) %>%
print()
Using only the sample observations, a plot was constructed below of
the overall mean (dashed line) along with the ecoregion-specific means
(black circles). The shaded areas indicate +/- 1 standard deviation.
Neither dissolved N2O nor the saturation ratio were clearly structured
by ecoregion in the sample, but there did appear to be some structure in
the equilibrium N2O observations.

The same summary by state is below.

Finally, the same summary by size category:

Sample data
exploration
Below, the empirical distribution of N2O observations in the sample
was summarized using a density and rug plot below. Note the natural log
scale of the x axis. Both the N2O and equilibrium N2O data had
considerable right skew even after the log transformation, which was not
unexpected and has been noted in other studies (Webb et al. 2019). The saturation ratio
was also skewed since it was derived from the other two observed
variables (i.e., sat_ratio = n2o / n2o_eq).

Below are plots of N2O vs. NO3. The first plot shows log(N2O)
vs. log(NO3), as well as the ordinal categories assigned to NO3
(vertical lines). The leftmost vertical line is dashed and separates the
NO3 observations below the detection limit.
`geom_smooth()` using formula = 'y ~ x'

In the plot above, the trend is increasing and nonlinear on the log
scale. The increasing variance in N2O along the NO3 gradeient suggested
a potential mediator of the relationship between NO3 on N2O. Below are
plots of N2O vs. NO3 for 6 quantiles of the surface temperature
measurements (quantiles increasing from 1 to 6). This plot below
suggested that the NO3 effect on N2O may have been stronger in lakes
with higher observed temperatures.
`geom_smooth()` using formula = 'y ~ x'

The next plot below shows the relationship between N2O and NO3 at 6
different quantiles (increasing 1 to 6) of the log-scaled lake surface
area estimates.
`geom_smooth()` using formula = 'y ~ x'

Similar plots are below, but with NO3 expressed as an ordered
categorical variable with 5 levels. The positive and monotonic trends
area similar to the previous plots where NO3 was treated as continuous.
Note the large number of observations in the first NO3 category (no3_cat
= 1). This category represented all of the censored observations for
NO3, which was most of the data.



Below is a plot of log(N2O) vs. log(NO3) by ecoregion, which
suggested that the NO3 effect on N2O may have varied by ecoregion.
`geom_smooth()` using formula = 'y ~ x'

Below is the same plot as above but for the ordered categorical
version of NO3.

A plot below shows trends by state within just the Temperate Plains
(TPL) ecoregion. Within states, the number of observations were
relatively small, but the trends appeared closer to linear.
`geom_smooth()` using formula = 'y ~ x'

Model fitting
The first regression model was constructed to estimate the joint
distribution of log-transformed N2O and equilibrium N2O conditional on
the the design factors. Each log-transformed observation, \(i \in 1,..,N=984\), for each response,
\(p \in 1:P=2\), was assumed to be
drawn from a multivariate normal distribution with the parameters \(\nu\) and \(\Sigma\), where \(\nu\) is the multivariate mean estimated
conditional on the design effects and \(\Sigma\) is a covariance matrix containing
the observation-level variances and residual correlation: \[Y \sim MVN(\nu, \Sigma)\]
The multivariate mean is a vector of mean parameters, \(\nu:[\mu_{p=1}, \mu_{p=2}]\), for each
response. Each mean is further defined by a linear combination of
parameters where, for each response \(p\) and observation \(i\):
\[\mu_{pi} = \alpha_{0(pi)} +
\alpha_{1(pij)} + \alpha_{2(pijk)} + \alpha_{3(pijkl)} \\
\alpha_1 \sim MVN(0, \Lambda_1) \\
\alpha_2 \sim MVN(0, \Lambda_2) \\
\alpha_3 \sim MVN(0, \Lambda_3)\]
The linear combination of parameters defining \(\mu\) above include a fixed global
intercept, \(a_0\), that is estimated
directly from the data, and three separate, latent group-level effects
matrices, \(\alpha_1, \alpha_2,
\alpha_3\). The group effects were assumed to be multivariate
normal and are centered on zero in multivariate space. The spread of the
effects around zero are determined by a covariance matrix, \(\Lambda_1, \Lambda_2, \text{or }
\Lambda_3\), which are estimated directly from the data. These
covariance terms are further defined where:
\[\Lambda = \begin{pmatrix} 1 &
\tau_{p=1} \\ \tau_{p=2} & 1 \end{pmatrix} \chi \begin{pmatrix} 1
& \tau_{p=1} \\ \tau_{p=2} & 1 \end{pmatrix}\]
The \(\tau\) parameters are the
group-level scale parameters, which constrain the spread of effects for
each response, and \(\chi\) comprises
the group-level residual correlation matrix:
\[\chi = \begin{pmatrix} 1 & \varrho
\\ \varrho & 1 \end{pmatrix}\]
wherein \(\varrho\) is the
group-level residual correlation between responses.
The explicit indexing in the notation above conveys the relationship
between the parameters and each observation, \(i\), and emphasizes the nested structure of
the observations within the group effects. Specifically, every
observation, \(i\), was nested in a
lake size category, \(l\), which was
nested in a state, \(k\), and
ecoregion, \(j\). The parameter \(\alpha_1\), therefore, accounted for
ecoregion-scale group effects or deviations from the global mean; \(\alpha_2\) accounted for state-level group
effects nested in ecoregions; and \(\alpha_3\) accounted for lake size group
effects within states and ecoregions.
Finally, the observation-level covariance term, \(\Sigma\), was parameterized as: \[\Sigma = \begin{pmatrix} 1 & \sigma_{p=1} \\
\sigma_{p=2} & 1 \end{pmatrix} \Omega \begin{pmatrix} 1 &
\sigma_{p=1} \\ \sigma_{p=2} & 1 \end{pmatrix}\]
wherein the \(\sigma\) parameters
are the observation-level standard deviations for each response and
\(\Omega\) comprises the
observation-level residual correlation matrix: \[\Omega = \begin{pmatrix} 1 & \rho \\ \rho
& 1 \end{pmatrix}\] wherein \(\rho\) is the residual correlation between
responses.
For model fitting, priors were needed for all parameters conditioned
directly on the data, which included the global intercept, the scale
parameters, and the correlation matrices. A normal or Gaussian prior,
\(N(\mu = 2, \sigma = 1)\) centered
near the (log-scale) data means, was used for the global intercept
parameter for each response. This prior was considered minimally
informative as it placed most (~80%) of the prior mass over values
between approximately 2 and 27 ng/L for median N2O or N2O equilibrium
concentration and included support in the tails for values approaching 0
ng/L on the lower end and 80 ng/L on the high end. We placed \(Exp(2)\) priors over all scale parameters,
which placed most of the support between values very close to 0 and
values near 1 (central 80% density interval from approximately 0.005 to
1.15). Finally, for the correlation matrices, an \(LKJ(\eta =2)\) prior was used, which, for a
2-dimensional response, placed most support for correlations between
approximately -0.9 and 0.9. This prior seemed reasonable as there was no
clear causal mechanisms that were thought to ensure a strong direct
correlation between the N2O measures. Any potential residual dependence
was expected to be indirect due to, for example, a common causal factor
(e.g., elevation, temperature). For more information on prior choice
recommendations in Stan, see: https://github.com/stan-dev/stan/wiki/Prior-Choice-Recommendations
The \(\textbf{brms}\) package (Bürkner 2017) for \(\textbf{R}\) (R Core Team
2021) was used to fit all of the models in a fully Bayesian
setting. The formula syntax of the \(\textbf{brms}\) package is similar to the
syntax used in the \(\textbf{lme4}\)
package that is widely used to fit mixed effects models in frequentist
settings In either package, the linear predictor for \(\mu\) described above could be expressed
as:
\[\sim 1 + (1|WSA9) + (1|WSA9:state) +
(1|WSA9:state:size)\]
In the \(\textbf{brms}\) package,
there is additionaly functionality and syntax for multivariate responses
and for allowing the varying intercepts in a multivariate model to be
correlated, e.g.,:
\[ N_2O_{dissolved}\sim 1 + (1|a|WSA9) +
(1|b|WSA9:state) + (1|c|WSA9:state:size) \\
N_2O_{equilibrium}\sim 1 + (1|a|WSA9) + (1|b|WSA9:state) +
(1|c|WSA9:state:size)\]
The above syntax would indicate that the linear predictor for both
responses in the multivariate model have the same group-level varying
effects, and that each of those effects are allowed to be correlated
between responses.
For the remainder of this document, only this simplified syntax is
presented to describe the model parameterizations. For more information
on \(\textbf{brms}\) functionality and
syntax with multivariate response models, the package vignette may be
helpful, and can be found at: https://cran.r-project.org/web/packages/brms/vignettes/brms_multivariate.html.
Model 1
The first model fit was the one described above.
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/df_model.rda")
bf_n2o <- bf(log(n2o) ~ 1 +
(1 | a | WSA9) +
(1 | b | WSA9:state) +
(1 | c | WSA9:state:size_cat),
family = gaussian())
bf_n2oeq <- bf(log(n2o_eq) ~ 1 +
(1 | a | WSA9) +
(1 | b | WSA9:state) +
(1 | c | WSA9:state:size_cat),
family = gaussian())
priors <- c(
prior(normal(2, 1), class = "Intercept", resp = "logn2o"), # centered near data mean
prior(exponential(2), class = "sd", resp = "logn2o"),
prior(exponential(2), class = "sigma", resp = "logn2o"),
prior(normal(2, 1), class = "Intercept", resp = "logn2oeq"), # centered near data mean
prior(exponential(2), class = "sd", resp = "logn2oeq"),
prior(exponential(2), class = "sigma", resp = "logn2oeq"),
prior(lkj(2), class = "rescor"),
prior(lkj(2), class = "cor")
)
n2o_mod1 <- brm(bf_n2o + bf_n2oeq + set_rescor(rescor = TRUE),
data = df_model,
prior = priors,
control = list(adapt_delta = 0.99, max_treedepth = 14),
#sample_prior = "only",
save_pars = save_pars(all = TRUE),
seed = 145,
chains=4,
iter=5000,
cores=4)
save(n2o_mod1, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/n2o_mod1.rda")
Summarize fit
The summaries of the estimated parameters and key HMC convergence
diagnostics for the fitted model are printed below. There were no
obvious issues with the HMC sampling. All \(\hat{R}\) values were less than 1.01 and
effective sample size (\(ESS\))
calculations suggested that the posterior contained a sufficient number
of effective samples for conducting inference.
Family: MV(gaussian, gaussian)
Links: mu = identity; sigma = identity
mu = identity; sigma = identity
Formula: log(n2o) ~ 1 + (1 | a | WSA9) + (1 | b | WSA9:state) + (1 | c | WSA9:state:size_cat)
log(n2o_eq) ~ 1 + (1 | a | WSA9) + (1 | b | WSA9:state) + (1 | c | WSA9:state:size_cat)
Data: df_model (Number of observations: 984)
Draws: 4 chains, each with iter = 5000; warmup = 2500; thin = 1;
total post-warmup draws = 10000
Priors:
Intercept_logn2o ~ normal(2, 1)
Intercept_logn2oeq ~ normal(2, 1)
L ~ lkj_corr_cholesky(2)
Lrescor ~ lkj_corr_cholesky(2)
<lower=0> sd_logn2o ~ exponential(2)
<lower=0> sd_logn2oeq ~ exponential(2)
<lower=0> sigma_logn2o ~ exponential(2)
<lower=0> sigma_logn2oeq ~ exponential(2)
Group-Level Effects:
~WSA9 (Number of levels: 9)
Estimate Est.Error l-95% CI u-95% CI Rhat
sd(logn2o_Intercept) 0.04 0.03 0.00 0.13 1.00
sd(logn2oeq_Intercept) 0.06 0.02 0.03 0.11 1.00
cor(logn2o_Intercept,logn2oeq_Intercept) 0.05 0.44 -0.80 0.83 1.01
Bulk_ESS Tail_ESS
sd(logn2o_Intercept) 2475 4230
sd(logn2oeq_Intercept) 3326 5332
cor(logn2o_Intercept,logn2oeq_Intercept) 1141 3129
~WSA9:state (Number of levels: 96)
Estimate Est.Error l-95% CI u-95% CI Rhat
sd(logn2o_Intercept) 0.26 0.03 0.21 0.32 1.00
sd(logn2oeq_Intercept) 0.04 0.01 0.03 0.05 1.00
cor(logn2o_Intercept,logn2oeq_Intercept) 0.24 0.15 -0.07 0.52 1.00
Bulk_ESS Tail_ESS
sd(logn2o_Intercept) 3199 4775
sd(logn2oeq_Intercept) 3549 5476
cor(logn2o_Intercept,logn2oeq_Intercept) 3332 5553
~WSA9:state:size_cat (Number of levels: 352)
Estimate Est.Error l-95% CI u-95% CI Rhat
sd(logn2o_Intercept) 0.09 0.04 0.01 0.16 1.00
sd(logn2oeq_Intercept) 0.02 0.01 0.00 0.03 1.00
cor(logn2o_Intercept,logn2oeq_Intercept) -0.22 0.37 -0.85 0.58 1.00
Bulk_ESS Tail_ESS
sd(logn2o_Intercept) 863 1397
sd(logn2oeq_Intercept) 928 1365
cor(logn2o_Intercept,logn2oeq_Intercept) 1661 2807
Population-Level Effects:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
logn2o_Intercept 2.02 0.04 1.95 2.09 1.00 2641 3963
logn2oeq_Intercept 2.00 0.02 1.96 2.04 1.00 3446 4550
Family Specific Parameters:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
sigma_logn2o 0.40 0.01 0.37 0.42 1.00 2749 5523
sigma_logn2oeq 0.08 0.00 0.08 0.09 1.00 4790 6698
Residual Correlations:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
rescor(logn2o,logn2oeq) 0.21 0.04 0.14 0.27 1.00 6172 7243
Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
and Tail_ESS are effective sample size measures, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).
In the summary above, the estimated standard deviations for the
varying group effects on the mean behavior of the dissolved N2O response
suggested fairly low, but non-zero variability across each of the three
levels. The standard deviations estimated for the same varying effects
for equilibrium N2O were also relatively small. Finally, note the
relatively small, but positive residual correlation between the two N2O
responses.
Before investing too much into the interpretation of this model,
however, the model fit was evaluated below using a series of graphical
posterior predictive checks [PPC; Gelman et al.
(2014);
Gelman, Hill, and Vehtari (2020), Ch.
11].
Model checks
Dissolved
N2O
Below are a series of panels illustrating graphical PPCs for the
log(N2O) component of the model. The top left panel compares a density
plot of the observed data (black line) to density lines drawn for 200
samples from the posterior predictive distribution (PPD; blue lines) of
the fitted model. The top right panel similarly compares the cumulative
density distributions. The left middle panel simulataneously compares
means vs. standard deviations for 1000 draws from the PPD (blue
dots) to the sample mean and standard deviation (black dot). The right
middle panel compares skewness vs. kurtosis for 1000 draws from
the PPD to the skewness and kurtosis values calculated for the observed
data. The bottom left panel compares max vs. min values for
1000 draws from the PPD to the max and min values of the sample data.
Finally, the bottom right panel shows the observed vs. average
predicted values for each observation in the sample. The average
predicted values were calculated as the mean prediction for each
observation in the PPD based on 1000 draws.

The general takeaway from the PPCs above was that the model
replicated the central tendency of the observed data fairly well, but
failed to sufficiently replicate other important aspects of the
distribution, such as skewness and kurtosis. The observed vs.
average predictions scatterplot suggested substantial heteroscedasticity
in the errors.
The same checks were run below, but for the test set of 95 held-out,
second-visit data points.

The patterns in misfit indicated above for the re-visit data were
similar to the patterns indicated in the PPCs with the training
data.
Equilibrium
N2O
Below are PPCs for the equilibrium N2O component of the model. As
with the dissolved N2O response above, the model did an OK job at
replicating the central tendency, but performed less well at replicating
some important aspects of the overall distribution.

Below are the same PPCs for equilibrium N2O in the re-visit
sites.

Bivariate
The graphical check below compares bivariate density contours
estimated from the observed data (black lines) to density contours
estimated for each of 20 draws from the PPD. The model appeared to do a
good job of replicating the bivariate mean, but was poor at representing
the overall joint distribution.

The same bivariate check is shown below for the re-visit data.

Saturation
The graphical PPCs below were aimed at evaluating how well the
multivariate model did at representing the observed saturation ratio:
\[N_2O_{dissolved}:N_2O_{equilibrium}\] This
quantity was estimated as a derived variable by simply dividing the N2O
PPD by the equilibrium N2O PPD. Likewise, the proportion of
under-saturated lakes in the sample was estimated by summing the number
of lakes from each posterior predictive draw wherein the ratio was <
1 and dividing that number by the total number of lakes in the sample,
which was 984. Overall, these checks indicated that properly
representing the tails of the N2O and N2O-eq observations would likely
be necessary in order to better replicate the observed saturation
metrics. For example, the model did a poor job replicating the observed
proportion of under-saturated lakes, underestimating it by more than 10
percentage points, on average.

The top left panel, above, is a density plot of the observed
saturation ratio (black line) compared to an estimate using 50 draws
from the model (blue lines). The top right panel shows the observed
proportion of under-saturated lakes compared to a model estimate based
on 1000 draws from the PPD. The left middle panel shows the mean
vs. standard deviation of the saturation ratio for the observed
data compared to the same estimates for 500 posterior draws from the
model’s PPD. The right middle panel shows the max vs. min for
the sample compared to 500 draws from the model’s PPD. Finally, the
bottom left panel shows the observed vs. average predicted
saturation ratio for all 984 lakes sampled in the dataset.
The same PPCs are show below for the revisit data.

The checks above indicated that the model did a similarly
underwhelming job of replicating some key properties of the saturation
metrics calculated from the re-visit data.
R-square
Below, the Bayesian \(R^2\) values
are reported for each reasponse in the model.
Estimate Est.Error Q2.5 Q97.5
R2logn2o 0.247 0.031 0.187 0.309
Estimate Est.Error Q2.5 Q97.5
R2logn2oeq 0.377 0.025 0.328 0.425
The \(R^2\) were also estimated for
the re-visit data.
Estimate Est.Error Q2.5 Q97.5
R2logn2o 0.413 0.04 0.331 0.489
Estimate Est.Error Q2.5 Q97.5
R2logn2oeq 0.322 0.026 0.271 0.374
Model 2
In an attempt to better fit the observed data, the next model
included distributional sub-models to allow for heterogeneous variances
for each response conditional on the survey design structure.
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/df_model.rda")
bf_n2o <- bf(log(n2o) ~ 1 +
(1 | a | WSA9) +
(1 | b | WSA9:state) +
(1 | c | WSA9:state:size_cat),
sigma ~ 1 +
(1 | WSA9) +
(1 | WSA9:state) +
(1 | WSA9:state:size_cat),
family = gaussian())
bf_n2oeq <- bf(log(n2o_eq) ~ 1 +
(1 | a | WSA9) +
(1 | b | WSA9:state) +
(1 | c | WSA9:state:size_cat),
sigma ~ 1 +
(1 | WSA9) +
(1 | WSA9:state) +
(1 | WSA9:state:size_cat),
family = gaussian())
priors <- c(
prior(normal(2, 1), class = "Intercept", resp = "logn2o"),
prior(exponential(2), class = "sd", resp = "logn2o"),
prior(normal(-1, 2), class = "Intercept", dpar = "sigma", resp = "logn2o"),
prior(exponential(2), class = "sd", dpar = "sigma", resp = "logn2o"),
prior(normal(2, 1), class = "Intercept", resp = "logn2oeq"),
prior(exponential(2), class = "sd", resp = "logn2oeq"),
prior(normal(-1, 2), class = "Intercept", dpar = "sigma", resp = "logn2oeq"),
prior(exponential(2), class = "sd", dpar = "sigma", resp = "logn2oeq"),
prior(lkj(2), class = "rescor"),
prior(lkj(2), class = "cor")
)
n2o_mod2 <- brm(bf_n2o + bf_n2oeq + set_rescor(rescor = TRUE),
data = df_model,
prior = priors,
control = list(adapt_delta = 0.975, max_treedepth = 12),
#sample_prior = "only",
save_pars = save_pars(all = TRUE),
seed = 84512,
chains=4,
iter=5000,
cores=4)
save(n2o_mod2, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/n2o_mod2.rda")
Summarize fit
The summaries of the estimated parameters and key HMC convergence
diagnostics for the fitted model are printed below.
Family: MV(gaussian, gaussian)
Links: mu = identity; sigma = log
mu = identity; sigma = log
Formula: log(n2o) ~ 1 + (1 | a | WSA9) + (1 | b | WSA9:state) + (1 | c | WSA9:state:size_cat)
sigma ~ 1 + (1 | WSA9) + (1 | WSA9:state) + (1 | WSA9:state:size_cat)
log(n2o_eq) ~ 1 + (1 | a | WSA9) + (1 | b | WSA9:state) + (1 | c | WSA9:state:size_cat)
sigma ~ 1 + (1 | WSA9) + (1 | WSA9:state) + (1 | WSA9:state:size_cat)
Data: df_model (Number of observations: 984)
Draws: 4 chains, each with iter = 5000; warmup = 2500; thin = 1;
total post-warmup draws = 10000
Priors:
Intercept_logn2o ~ normal(2, 1)
Intercept_logn2o_sigma ~ normal(-1, 2)
Intercept_logn2oeq ~ normal(2, 1)
Intercept_logn2oeq_sigma ~ normal(-1, 2)
L ~ lkj_corr_cholesky(2)
Lrescor ~ lkj_corr_cholesky(2)
<lower=0> sd_logn2o ~ exponential(2)
<lower=0> sd_logn2o_sigma ~ exponential(2)
<lower=0> sd_logn2oeq ~ exponential(2)
<lower=0> sd_logn2oeq_sigma ~ exponential(2)
Group-Level Effects:
~WSA9 (Number of levels: 9)
Estimate Est.Error l-95% CI u-95% CI Rhat
sd(logn2o_Intercept) 0.06 0.03 0.02 0.12 1.00
sd(logn2oeq_Intercept) 0.05 0.02 0.03 0.09 1.00
sd(sigma_logn2o_Intercept) 0.22 0.12 0.02 0.50 1.00
sd(sigma_logn2oeq_Intercept) 0.16 0.08 0.04 0.34 1.00
cor(logn2o_Intercept,logn2oeq_Intercept) 0.57 0.30 -0.18 0.95 1.00
Bulk_ESS Tail_ESS
sd(logn2o_Intercept) 2247 1772
sd(logn2oeq_Intercept) 3423 4761
sd(sigma_logn2o_Intercept) 1892 3094
sd(sigma_logn2oeq_Intercept) 2413 1991
cor(logn2o_Intercept,logn2oeq_Intercept) 2696 3538
~WSA9:state (Number of levels: 96)
Estimate Est.Error l-95% CI u-95% CI Rhat
sd(logn2o_Intercept) 0.08 0.02 0.04 0.11 1.00
sd(logn2oeq_Intercept) 0.04 0.01 0.03 0.05 1.00
sd(sigma_logn2o_Intercept) 0.56 0.08 0.40 0.74 1.00
sd(sigma_logn2oeq_Intercept) 0.22 0.05 0.11 0.32 1.00
cor(logn2o_Intercept,logn2oeq_Intercept) 0.42 0.19 -0.00 0.74 1.00
Bulk_ESS Tail_ESS
sd(logn2o_Intercept) 1276 1733
sd(logn2oeq_Intercept) 2695 5090
sd(sigma_logn2o_Intercept) 2007 3462
sd(sigma_logn2oeq_Intercept) 1851 1881
cor(logn2o_Intercept,logn2oeq_Intercept) 1076 1960
~WSA9:state:size_cat (Number of levels: 352)
Estimate Est.Error l-95% CI u-95% CI Rhat
sd(logn2o_Intercept) 0.06 0.01 0.03 0.09 1.00
sd(logn2oeq_Intercept) 0.02 0.01 0.00 0.03 1.00
sd(sigma_logn2o_Intercept) 0.61 0.05 0.51 0.72 1.00
sd(sigma_logn2oeq_Intercept) 0.19 0.06 0.07 0.29 1.00
cor(logn2o_Intercept,logn2oeq_Intercept) -0.00 0.34 -0.70 0.62 1.00
Bulk_ESS Tail_ESS
sd(logn2o_Intercept) 1329 2182
sd(logn2oeq_Intercept) 1052 1452
sd(sigma_logn2o_Intercept) 2622 4939
sd(sigma_logn2oeq_Intercept) 1603 1725
cor(logn2o_Intercept,logn2oeq_Intercept) 996 2063
Population-Level Effects:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
logn2o_Intercept 1.93 0.03 1.88 1.99 1.00 3338 4462
sigma_logn2o_Intercept -1.40 0.12 -1.63 -1.17 1.00 3511 5077
logn2oeq_Intercept 2.00 0.02 1.96 2.03 1.00 3384 4145
sigma_logn2oeq_Intercept -2.60 0.07 -2.75 -2.45 1.00 4004 4848
Residual Correlations:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
rescor(logn2o,logn2oeq) 0.36 0.03 0.29 0.43 1.00 6474 7733
Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
and Tail_ESS are effective sample size measures, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).
From the summary above, note the moderate and positive residual
correlation between the two N2O responses. The estimated standard
deviations for the varying group effects on the mean behavior of the
dissolved N2O response suggested fairly low, but non-zero variability
across each of the three levels. The standard deviations estimated for
the same varying effects for equilibrium N2O were also relatively small.
However, before investing too much into the interpretation of these
results, the model fit was further evaluated below using a series of
graphical posterior predictive checks (PPCs).
Model checks
Below the same PPCs were performed as with the initial model (see
above for more details on each panel). ##### Dissolved N2O Though the
checks below suggest some improvement in replicating the tails of the
observed data, this model did a poorer job at replicating central
tendency.

Equilibrium
N2O
The checks below suggest this model offered no improvement upon the
initial model for equilibrium N2O. This model also appeared to do a
poorer job of replicating the mean and overall standard deviation
compared to the initial model.

Bivariate
This check perhaps suggested an improvement with regard to
replicating the joint density. However, the predictions were still
clearly over-dispersed relative to the observations.

Saturation
The PPCs for the saturation metrics below indicated that including
the distributional models was perhaps an improvement on the initial
model in some aspects; in particular, the bias in the predicted
proportion of under-saturated lakes was substantially decreased.
However, there appeared to still be issues in replicating the tails as
well as issues with central tendency.

R-square
Relative to model 1, there was a substantial decrease in the \(R^2\) estimate for the dissolved N2O
component of this model. The estimate for the equilibrium N2O-eq
component was similar to the model 1.
Estimate Est.Error Q2.5 Q97.5
R2logn2o 0.056 0.009 0.038 0.075
Estimate Est.Error Q2.5 Q97.5
R2logn2oeq 0.379 0.022 0.335 0.421
Model 3
In the next model, we used covariates to try to improve the fit. The
categorical version of the NO3 covariate was used as a monotonic ordinal
predictor in the dissolved N2O component of the modl. For the equlibrium
N2O component, we included surface temperature and log-transformed
elevation, along with their interaction. The models also retained the
distributional specifications included in model 2 above.
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/df_model.rda")
bf_n2o <- bf(log(n2o) ~ mo(no3_cat) +
surftemp +
(mo(no3_cat) | a | WSA9) +
(mo(no3_cat) | b | WSA9:state) +
(1 | c | WSA9:state:size_cat),
sigma ~ 1 +
(1 | WSA9) +
(1 | WSA9:state) +
(1 | WSA9:state:size_cat),
family = gaussian())
bf_n2oeq <- bf(log(n2o_eq) ~ surftemp +
log_elev +
surftemp:log_elev +
(1 | a | WSA9) +
(1 | b | WSA9:state) +
(1 | c | WSA9:state:size_cat),
sigma ~ 1 +
(1 | WSA9) +
(1 | WSA9:state) +
(1 | WSA9:state:size_cat),
family = gaussian())
priors <- c(
prior(normal(2, 1), class = "Intercept", resp = "logn2o"),
prior(normal(0, 1), class = "b", resp = "logn2o"),
prior(exponential(2), class = "sd", resp = "logn2o"),
prior(normal(-1, 2), class = "Intercept", dpar = "sigma", resp = "logn2o"),
prior(exponential(2), class = "sd", dpar = "sigma", resp = "logn2o"),
prior(normal(2, 1), class = "Intercept", resp = "logn2oeq"),
prior(normal(0, 1), class = "b", resp = "logn2oeq"),
prior(exponential(2), class = "sd", resp = "logn2oeq"),
prior(normal(-1, 2), class = "Intercept", dpar = "sigma", resp = "logn2oeq"),
prior(exponential(2), class = "sd", dpar = "sigma", resp = "logn2oeq"),
prior(lkj(2), class = "rescor"),
prior(lkj(2), class = "cor")
)
n2o_mod3 <- brm(bf_n2o + bf_n2oeq + set_rescor(rescor = TRUE),
data = df_model,
prior = priors,
control = list(adapt_delta = 0.975, max_treedepth = 12),
#sample_prior = "only",
save_pars = save_pars(all = TRUE),
seed = 98456,
chains=4,
iter=5000,
cores=4)
save(n2o_mod3, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/n2o_mod3.rda")
Summarize fit
The fitted parameters and MCMC diagnostics are below.
Family: MV(gaussian, gaussian)
Links: mu = identity; sigma = log
mu = identity; sigma = log
Formula: log(n2o) ~ mo(no3_cat) + surftemp + (mo(no3_cat) | a | WSA9) + (mo(no3_cat) | b | WSA9:state) + (1 | c | WSA9:state:size_cat)
sigma ~ 1 + (1 | WSA9) + (1 | WSA9:state) + (1 | WSA9:state:size_cat)
log(n2o_eq) ~ surftemp + log_elev + surftemp:log_elev + (1 | a | WSA9) + (1 | b | WSA9:state) + (1 | c | WSA9:state:size_cat)
sigma ~ 1 + (1 | WSA9) + (1 | WSA9:state) + (1 | WSA9:state:size_cat)
Data: df_model (Number of observations: 984)
Draws: 4 chains, each with iter = 5000; warmup = 2500; thin = 1;
total post-warmup draws = 10000
Priors:
b_logn2o ~ normal(0, 1)
b_logn2oeq ~ normal(0, 1)
Intercept_logn2o ~ normal(2, 1)
Intercept_logn2o_sigma ~ normal(-1, 2)
Intercept_logn2oeq ~ normal(2, 1)
Intercept_logn2oeq_sigma ~ normal(-1, 2)
L ~ lkj_corr_cholesky(2)
Lrescor ~ lkj_corr_cholesky(2)
<lower=0> sd_logn2o ~ exponential(2)
<lower=0> sd_logn2o_sigma ~ exponential(2)
<lower=0> sd_logn2oeq ~ exponential(2)
<lower=0> sd_logn2oeq_sigma ~ exponential(2)
simo_logn2o_mono3_cat1 ~ dirichlet(1)
Group-Level Effects:
~WSA9 (Number of levels: 9)
Estimate Est.Error l-95% CI u-95% CI Rhat
sd(logn2o_Intercept) 0.05 0.02 0.02 0.10 1.00
sd(logn2o_mono3_cat) 0.14 0.05 0.06 0.26 1.00
sd(logn2oeq_Intercept) 0.04 0.01 0.02 0.07 1.00
sd(sigma_logn2o_Intercept) 0.12 0.08 0.01 0.31 1.00
sd(sigma_logn2oeq_Intercept) 0.36 0.11 0.19 0.64 1.00
cor(logn2o_Intercept,logn2o_mono3_cat) -0.14 0.33 -0.72 0.53 1.00
cor(logn2o_Intercept,logn2oeq_Intercept) 0.36 0.29 -0.28 0.83 1.00
cor(logn2o_mono3_cat,logn2oeq_Intercept) 0.37 0.29 -0.26 0.82 1.00
Bulk_ESS Tail_ESS
sd(logn2o_Intercept) 4265 3917
sd(logn2o_mono3_cat) 4747 5482
sd(logn2oeq_Intercept) 4798 5704
sd(sigma_logn2o_Intercept) 3419 4599
sd(sigma_logn2oeq_Intercept) 5027 6638
cor(logn2o_Intercept,logn2o_mono3_cat) 4970 6018
cor(logn2o_Intercept,logn2oeq_Intercept) 5073 6636
cor(logn2o_mono3_cat,logn2oeq_Intercept) 7256 7538
~WSA9:state (Number of levels: 96)
Estimate Est.Error l-95% CI u-95% CI Rhat
sd(logn2o_Intercept) 0.03 0.02 0.00 0.07 1.00
sd(logn2o_mono3_cat) 0.14 0.02 0.10 0.18 1.00
sd(logn2oeq_Intercept) 0.03 0.00 0.03 0.04 1.00
sd(sigma_logn2o_Intercept) 0.30 0.09 0.09 0.47 1.00
sd(sigma_logn2oeq_Intercept) 0.28 0.06 0.17 0.40 1.00
cor(logn2o_Intercept,logn2o_mono3_cat) -0.30 0.32 -0.82 0.45 1.00
cor(logn2o_Intercept,logn2oeq_Intercept) 0.00 0.27 -0.53 0.55 1.01
cor(logn2o_mono3_cat,logn2oeq_Intercept) 0.45 0.13 0.16 0.69 1.00
Bulk_ESS Tail_ESS
sd(logn2o_Intercept) 894 2100
sd(logn2o_mono3_cat) 3795 5396
sd(logn2oeq_Intercept) 4164 5957
sd(sigma_logn2o_Intercept) 1157 1279
sd(sigma_logn2oeq_Intercept) 2747 4313
cor(logn2o_Intercept,logn2o_mono3_cat) 550 693
cor(logn2o_Intercept,logn2oeq_Intercept) 596 971
cor(logn2o_mono3_cat,logn2oeq_Intercept) 2536 4431
~WSA9:state:size_cat (Number of levels: 352)
Estimate Est.Error l-95% CI u-95% CI Rhat
sd(logn2o_Intercept) 0.06 0.01 0.04 0.08 1.00
sd(logn2oeq_Intercept) 0.00 0.00 0.00 0.01 1.00
sd(sigma_logn2o_Intercept) 0.58 0.06 0.47 0.70 1.00
sd(sigma_logn2oeq_Intercept) 0.28 0.05 0.18 0.39 1.00
cor(logn2o_Intercept,logn2oeq_Intercept) 0.26 0.39 -0.60 0.87 1.00
Bulk_ESS Tail_ESS
sd(logn2o_Intercept) 1429 2386
sd(logn2oeq_Intercept) 1779 3895
sd(sigma_logn2o_Intercept) 2003 4421
sd(sigma_logn2oeq_Intercept) 1812 3745
cor(logn2o_Intercept,logn2oeq_Intercept) 4523 5554
Population-Level Effects:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
logn2o_Intercept 2.40 0.05 2.29 2.50 1.00 5046 6296
sigma_logn2o_Intercept -1.70 0.08 -1.87 -1.55 1.00 5162 5452
logn2oeq_Intercept 3.10 0.05 3.01 3.19 1.00 8903 7808
sigma_logn2oeq_Intercept -3.54 0.14 -3.81 -3.27 1.00 4065 5338
logn2o_surftemp -0.02 0.00 -0.03 -0.02 1.00 5529 6684
logn2oeq_surftemp -0.04 0.00 -0.04 -0.04 1.00 9722 7658
logn2oeq_log_elev -0.07 0.01 -0.09 -0.06 1.00 9200 7505
logn2oeq_surftemp:log_elev 0.00 0.00 0.00 0.00 1.00 9527 8028
logn2o_mono3_cat 0.23 0.05 0.12 0.34 1.00 3948 4777
Simplex Parameters:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
logn2o_mono3_cat1[1] 0.02 0.01 0.00 0.04 1.00 5535 5409
logn2o_mono3_cat1[2] 0.09 0.02 0.04 0.13 1.00 4281 5251
logn2o_mono3_cat1[3] 0.21 0.05 0.13 0.32 1.00 3683 4649
logn2o_mono3_cat1[4] 0.69 0.05 0.58 0.77 1.00 3498 4251
Residual Correlations:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
rescor(logn2o,logn2oeq) 0.15 0.04 0.07 0.23 1.00 11381 7610
Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
and Tail_ESS are effective sample size measures, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).
Model checks
Dissolved
N2O
The PPCs below indicated a better fit compared to the previous
models. The central tendency and tail behavior looked to be reasonably
replicated by comparison. However, the observed vs. predicted
plot suggested that larger overserved values were being systematically
underestimated.

Equilibrium
N2O
The PPCs below indicated that this model appeared to be an
improvement for equilibrium N2O as well. However, some checks (e.g.,
skewness) suggested some room for additional improvement.

Bivariate
The check for the joint distribution below also suggested an
improvement up the previous models.

Saturation
This model looked to be an improvement with regard to the PPCs for
the saturation metrics. However, the proportion of under-saturated lakes
remained biased low and other checks indicated that further improvements
would be ideal.

R-square
The \(R^2\) estimates for this model
are below and suggested substantial improvements on the previous
models.
Estimate Est.Error Q2.5 Q97.5
R2logn2o 0.626 0.017 0.591 0.66
Estimate Est.Error Q2.5 Q97.5
R2logn2oeq 0.879 0.004 0.87 0.886
Covariate
effects
Below are plots illustrating the modeled effects of covariates on
both N2O and equilibrium N2O. #### N2O The conditional effects plots
below for N2O illustrate a positive, monotonic, and non-linear
relationship between NO3 and N2O; and a negative, linear relationship
between surface temperature and N2O.

Equilibrium
N2O
The modeled effects below for the equilibrium N2O component of the
model illustrated a negative relationship between equilibrium N2O and
both predictors and an interaction such that the surface temperature
effect became slightly steeper at lower elevations.

Model 4
In the next model, covariate terms were also included in the \(\sigma\) components of both models in order
to try to better capture remaining heterogeneity in the variances of
both N2O and N2O-eq.
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/df_model.rda")
bf_n2o <- bf(log(n2o) ~ mo(no3_cat) +
surftemp +
(mo(no3_cat) | a | WSA9) +
(mo(no3_cat) | b | WSA9:state) +
(1 | c | WSA9:state:size_cat),
sigma ~ mo(no3_cat) +
surftemp +
(1 | WSA9) +
(1 | WSA9:state) +
(1 | WSA9:state:size_cat),
family = gaussian())
bf_n2oeq <- bf(log(n2o_eq) ~ surftemp +
log_elev +
surftemp:log_elev +
(1 | a | WSA9) +
(1 | b | WSA9:state) +
(1 | c | WSA9:state:size_cat),
sigma ~ surftemp +
log_elev +
(1 | WSA9) +
(1 | WSA9:state) +
(1 | WSA9:state:size_cat),
family = gaussian())
priors <- c(
prior(normal(2, 1), class = "Intercept", resp = "logn2o"),
prior(normal(0, 1), class = "b", resp = "logn2o"),
prior(exponential(2), class = "sd", resp = "logn2o"),
prior(normal(-1, 2), class = "Intercept", dpar = "sigma", resp = "logn2o"),
prior(normal(0, 1), class = "b", dpar = "sigma", resp = "logn2o"),
prior(exponential(2), class = "sd", dpar = "sigma", resp = "logn2o"),
prior(normal(2, 1), class = "Intercept", resp = "logn2oeq"),
prior(normal(0, 1), class = "b", resp = "logn2oeq"),
prior(exponential(2), class = "sd", resp = "logn2oeq"),
prior(normal(-1, 2), class = "Intercept", dpar = "sigma", resp = "logn2oeq"),
prior(normal(0, 1), class = "b", dpar = "sigma", resp = "logn2oeq"),
prior(exponential(2), class = "sd", dpar = "sigma", resp = "logn2oeq"),
prior(lkj(2), class = "rescor"),
prior(lkj(2), class = "cor")
)
n2o_mod4 <- brm(bf_n2o + bf_n2oeq + set_rescor(rescor = TRUE),
data = df_model,
prior = priors,
control = list(adapt_delta = 0.975, max_treedepth = 12),
#sample_prior = "only",
save_pars = save_pars(all = TRUE),
seed = 15851,
chains=4,
iter=5000,
cores=4)
save(n2o_mod4, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/n2o_mod4.rda")
Summarize fit
Below is a summary of the fitted parameters along with some
convergence diagnostics.
Family: MV(gaussian, gaussian)
Links: mu = identity; sigma = log
mu = identity; sigma = log
Formula: log(n2o) ~ mo(no3_cat) + surftemp + (mo(no3_cat) | a | WSA9) + (mo(no3_cat) | b | WSA9:state) + (1 | c | WSA9:state:size_cat)
sigma ~ mo(no3_cat) + surftemp + (1 | WSA9) + (1 | WSA9:state) + (1 | WSA9:state:size_cat)
log(n2o_eq) ~ surftemp + log_elev + surftemp:log_elev + (1 | a | WSA9) + (1 | b | WSA9:state) + (1 | c | WSA9:state:size_cat)
sigma ~ surftemp + log_elev + (1 | WSA9) + (1 | WSA9:state) + (1 | WSA9:state:size_cat)
Data: df_model (Number of observations: 984)
Draws: 4 chains, each with iter = 5000; warmup = 2500; thin = 1;
total post-warmup draws = 10000
Priors:
b_logn2o ~ normal(0, 1)
b_logn2o_sigma ~ normal(0, 1)
b_logn2oeq ~ normal(0, 1)
b_logn2oeq_sigma ~ normal(0, 1)
Intercept_logn2o ~ normal(2, 1)
Intercept_logn2o_sigma ~ normal(-1, 2)
Intercept_logn2oeq ~ normal(2, 1)
Intercept_logn2oeq_sigma ~ normal(-1, 2)
L ~ lkj_corr_cholesky(2)
Lrescor ~ lkj_corr_cholesky(2)
<lower=0> sd_logn2o ~ exponential(2)
<lower=0> sd_logn2o_sigma ~ exponential(2)
<lower=0> sd_logn2oeq ~ exponential(2)
<lower=0> sd_logn2oeq_sigma ~ exponential(2)
simo_logn2o_mono3_cat1 ~ dirichlet(1)
simo_logn2o_sigma_mono3_cat1 ~ dirichlet(1)
Group-Level Effects:
~WSA9 (Number of levels: 9)
Estimate Est.Error l-95% CI u-95% CI Rhat
sd(logn2o_Intercept) 0.050 0.020 0.020 0.100 1.000
sd(logn2o_mono3_cat) 0.145 0.054 0.065 0.272 1.000
sd(logn2oeq_Intercept) 0.036 0.012 0.019 0.065 1.001
sd(sigma_logn2o_Intercept) 0.113 0.080 0.005 0.303 1.001
sd(sigma_logn2oeq_Intercept) 0.208 0.098 0.039 0.435 1.001
cor(logn2o_Intercept,logn2o_mono3_cat) -0.186 0.327 -0.755 0.489 1.000
cor(logn2o_Intercept,logn2oeq_Intercept) 0.344 0.290 -0.277 0.817 1.000
cor(logn2o_mono3_cat,logn2oeq_Intercept) 0.364 0.286 -0.269 0.819 1.001
Bulk_ESS Tail_ESS
sd(logn2o_Intercept) 4733 4348
sd(logn2o_mono3_cat) 4386 6208
sd(logn2oeq_Intercept) 3977 5215
sd(sigma_logn2o_Intercept) 2543 4693
sd(sigma_logn2oeq_Intercept) 2777 2177
cor(logn2o_Intercept,logn2o_mono3_cat) 4616 6092
cor(logn2o_Intercept,logn2oeq_Intercept) 5667 6074
cor(logn2o_mono3_cat,logn2oeq_Intercept) 7634 7624
~WSA9:state (Number of levels: 96)
Estimate Est.Error l-95% CI u-95% CI Rhat
sd(logn2o_Intercept) 0.035 0.017 0.003 0.068 1.001
sd(logn2o_mono3_cat) 0.117 0.022 0.076 0.162 1.001
sd(logn2oeq_Intercept) 0.033 0.003 0.027 0.040 1.000
sd(sigma_logn2o_Intercept) 0.181 0.099 0.011 0.374 1.004
sd(sigma_logn2oeq_Intercept) 0.287 0.057 0.177 0.403 1.001
cor(logn2o_Intercept,logn2o_mono3_cat) -0.317 0.311 -0.810 0.405 1.003
cor(logn2o_Intercept,logn2oeq_Intercept) 0.025 0.265 -0.497 0.557 1.005
cor(logn2o_mono3_cat,logn2oeq_Intercept) 0.448 0.165 0.098 0.738 1.001
Bulk_ESS Tail_ESS
sd(logn2o_Intercept) 981 2017
sd(logn2o_mono3_cat) 3149 4612
sd(logn2oeq_Intercept) 3457 6360
sd(sigma_logn2o_Intercept) 858 2373
sd(sigma_logn2oeq_Intercept) 2470 3862
cor(logn2o_Intercept,logn2o_mono3_cat) 945 1286
cor(logn2o_Intercept,logn2oeq_Intercept) 556 823
cor(logn2o_mono3_cat,logn2oeq_Intercept) 1518 3021
~WSA9:state:size_cat (Number of levels: 352)
Estimate Est.Error l-95% CI u-95% CI Rhat
sd(logn2o_Intercept) 0.065 0.011 0.042 0.087 1.003
sd(logn2oeq_Intercept) 0.004 0.002 0.000 0.008 1.001
sd(sigma_logn2o_Intercept) 0.539 0.055 0.432 0.647 1.002
sd(sigma_logn2oeq_Intercept) 0.263 0.051 0.162 0.363 1.001
cor(logn2o_Intercept,logn2oeq_Intercept) 0.395 0.348 -0.479 0.904 1.001
Bulk_ESS Tail_ESS
sd(logn2o_Intercept) 1478 2832
sd(logn2oeq_Intercept) 1506 2453
sd(sigma_logn2o_Intercept) 1443 3611
sd(sigma_logn2oeq_Intercept) 2372 4366
cor(logn2o_Intercept,logn2oeq_Intercept) 4231 4956
Population-Level Effects:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
logn2o_Intercept 2.386 0.055 2.278 2.490 1.000 5971 7057
sigma_logn2o_Intercept -1.855 0.281 -2.389 -1.294 1.000 5965 7704
logn2oeq_Intercept 3.115 0.051 3.016 3.217 1.001 7109 7366
sigma_logn2oeq_Intercept -1.922 0.373 -2.634 -1.180 1.000 8445 7581
logn2o_surftemp -0.021 0.002 -0.026 -0.017 1.000 5850 7677
sigma_logn2o_surftemp -0.001 0.011 -0.023 0.021 1.001 6175 7768
logn2oeq_surftemp -0.042 0.002 -0.046 -0.039 1.001 8285 7516
logn2oeq_log_elev -0.080 0.008 -0.096 -0.065 1.001 7656 7564
logn2oeq_surftemp:log_elev 0.002 0.000 0.002 0.003 1.000 8407 7502
sigma_logn2oeq_surftemp -0.065 0.010 -0.085 -0.046 1.000 10043 8163
sigma_logn2oeq_log_elev -0.019 0.038 -0.095 0.054 1.000 6646 7910
logn2o_mono3_cat 0.225 0.058 0.108 0.340 1.000 4488 5143
sigma_logn2o_mono3_cat 0.256 0.037 0.187 0.331 1.000 6036 7643
Simplex Parameters:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
logn2o_mono3_cat1[1] 0.018 0.012 0.001 0.045 1.000 5709 4429
logn2o_mono3_cat1[2] 0.093 0.027 0.041 0.149 1.000 5034 5645
logn2o_mono3_cat1[3] 0.231 0.060 0.126 0.366 1.000 4974 5478
logn2o_mono3_cat1[4] 0.659 0.062 0.520 0.763 1.000 4446 5210
sigma_logn2o_mono3_cat1[1] 0.107 0.066 0.007 0.255 1.000 6168 4471
sigma_logn2o_mono3_cat1[2] 0.129 0.087 0.006 0.328 1.000 8105 5010
sigma_logn2o_mono3_cat1[3] 0.459 0.151 0.168 0.758 1.000 7272 5802
sigma_logn2o_mono3_cat1[4] 0.304 0.139 0.038 0.569 1.000 6289 4264
Residual Correlations:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
rescor(logn2o,logn2oeq) 0.146 0.040 0.067 0.223 1.001 9839 8508
Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
and Tail_ESS are effective sample size measures, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).
Model checks
Again, the same PPCs were employed for this model as above. ####
Dissolved N2O Again, this model appeared to be an improvement on the
previous model, particularly with regard to the more constant variance
indicated in the observed vs. predicted plot (bottom, right
panel).
Using all posterior draws for ppc type 'scatter_avg' by default.

Equilibrium
N2O
This component of the model also seemed to be an improvement over
model 3, with better representation in the tails as indicated in the
skewness vs. kurtosis PPC.

Bivariate
Again, an improvement over the previous model with a tighter fit of
the PPC to the observed bivariate density.

Saturation
This check also suggested an improvement over the previous models,
with better tail behavior and less bias in the proportion
under-saturated measure.

R-square
The Bayesian \(R^2\) estimates below
indicated an improvement from the previous models.
Estimate Est.Error Q2.5 Q97.5
R2logn2o 0.606 0.025 0.551 0.651
Estimate Est.Error Q2.5 Q97.5
R2logn2oeq 0.875 0.005 0.865 0.883
Covariate
effects
N2O
The conditional effects plots for the covariate effects on N2O
remained largely unchanged from the previous model.

Below are estimates of the conditional effects of the covariates on
\(\sigma\) for N2O. These plots
suggested a large effect of NO3 on the variance of N2O, but little to no
effect of surface temperature.

Equilibrium
N2O
The covariate effects on N2O remained largely the same as for the
previous model.

The covariate effects on \(\sigma\)
for N2O-eq suggested an negative effect of surface temperature and litte
to no effect of elevation.

Model 5
In the next model, more complexity is added to the N2O component by
including a covariate for lake surface area (log scale) as well as
interactions between NO3 and log(area) and surface temperature.
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/df_model.rda")
bf_n2o <- bf(log(n2o) ~ mo(no3_cat) +
log_area +
surftemp +
mo(no3_cat):log_area +
mo(no3_cat):surftemp +
(mo(no3_cat) | a | WSA9) +
(mo(no3_cat) | b | WSA9:state) +
(1 | c | WSA9:state:size_cat),
sigma ~ log_area +
mo(no3_cat) +
(1 | WSA9) +
(1 | WSA9:state) +
(1 | WSA9:state:size_cat),
family = gaussian())
bf_n2oeq <- bf(log(n2o_eq) ~ surftemp +
log_elev +
surftemp:log_elev +
(1 | a | WSA9) +
(1 | b | WSA9:state) +
(1 | c | WSA9:state:size_cat),
sigma ~ surftemp +
log_elev +
(1 | WSA9) +
(1 | WSA9:state) +
(1 | WSA9:state:size_cat),
family = gaussian())
priors <- c(
prior(normal(2, 1), class = "Intercept", resp = "logn2o"),
prior(normal(0, 1), class = "b", resp = "logn2o"),
prior(exponential(2), class = "sd", resp = "logn2o"),
prior(normal(-1, 2), class = "Intercept", dpar = "sigma", resp = "logn2o"),
prior(normal(0, 1), class = "b", dpar = "sigma", resp = "logn2o"),
prior(exponential(2), class = "sd", dpar = "sigma", resp = "logn2o"),
prior(normal(2, 1), class = "Intercept", resp = "logn2oeq"),
prior(normal(0, 1), class = "b", resp = "logn2oeq"),
prior(exponential(2), class = "sd", resp = "logn2oeq"),
prior(normal(-1, 2), class = "Intercept", dpar = "sigma", resp = "logn2oeq"),
prior(normal(0, 1), class = "b", dpar = "sigma", resp = "logn2oeq"),
prior(exponential(2), class = "sd", dpar = "sigma", resp = "logn2oeq"),
prior(lkj(2), class = "rescor"),
prior(lkj(2), class = "cor")
)
n2o_mod5 <- brm(bf_n2o +
bf_n2oeq +
set_rescor(rescor = TRUE),
data = df_model,
prior = priors,
control = list(adapt_delta = 0.975, max_treedepth = 12),
#sample_prior = "only",
save_pars = save_pars(all = TRUE),
seed = 54741,
chains=4,
iter=5000,
cores=4)
save(n2o_mod5, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/n2o_mod5.rda")
Summarize fit
Below is a summary of the fitted parameters along with MCMC
convergence diagnostics.
Family: MV(gaussian, gaussian)
Links: mu = identity; sigma = log
mu = identity; sigma = log
Formula: log(n2o) ~ mo(no3_cat) + log_area + surftemp + mo(no3_cat):log_area + mo(no3_cat):surftemp + (mo(no3_cat) | a | WSA9) + (mo(no3_cat) | b | WSA9:state) + (1 | c | WSA9:state:size_cat)
sigma ~ log_area + mo(no3_cat) + (1 | WSA9) + (1 | WSA9:state) + (1 | WSA9:state:size_cat)
log(n2o_eq) ~ surftemp + log_elev + surftemp:log_elev + (1 | a | WSA9) + (1 | b | WSA9:state) + (1 | c | WSA9:state:size_cat)
sigma ~ surftemp + log_elev + (1 | WSA9) + (1 | WSA9:state) + (1 | WSA9:state:size_cat)
Data: df_model (Number of observations: 984)
Draws: 4 chains, each with iter = 5000; warmup = 2500; thin = 1;
total post-warmup draws = 10000
Priors:
b_logn2o ~ normal(0, 1)
b_logn2o_sigma ~ normal(0, 1)
b_logn2oeq ~ normal(0, 1)
b_logn2oeq_sigma ~ normal(0, 1)
Intercept_logn2o ~ normal(2, 1)
Intercept_logn2o_sigma ~ normal(-1, 2)
Intercept_logn2oeq ~ normal(2, 1)
Intercept_logn2oeq_sigma ~ normal(-1, 2)
L ~ lkj_corr_cholesky(2)
Lrescor ~ lkj_corr_cholesky(2)
<lower=0> sd_logn2o ~ exponential(2)
<lower=0> sd_logn2o_sigma ~ exponential(2)
<lower=0> sd_logn2oeq ~ exponential(2)
<lower=0> sd_logn2oeq_sigma ~ exponential(2)
simo_logn2o_mono3_cat:log_area1 ~ dirichlet(1)
simo_logn2o_mono3_cat:surftemp1 ~ dirichlet(1)
simo_logn2o_mono3_cat1 ~ dirichlet(1)
simo_logn2o_sigma_mono3_cat1 ~ dirichlet(1)
Group-Level Effects:
~WSA9 (Number of levels: 9)
Estimate Est.Error l-95% CI u-95% CI Rhat
sd(logn2o_Intercept) 0.048 0.019 0.020 0.094 1.000
sd(logn2o_mono3_cat) 0.081 0.050 0.007 0.199 1.003
sd(logn2oeq_Intercept) 0.034 0.011 0.018 0.062 1.000
sd(sigma_logn2o_Intercept) 0.111 0.076 0.006 0.293 1.000
sd(sigma_logn2oeq_Intercept) 0.209 0.102 0.036 0.445 1.001
cor(logn2o_Intercept,logn2o_mono3_cat) -0.056 0.360 -0.713 0.644 1.000
cor(logn2o_Intercept,logn2oeq_Intercept) 0.464 0.284 -0.173 0.885 1.000
cor(logn2o_mono3_cat,logn2oeq_Intercept) 0.259 0.341 -0.467 0.824 1.000
Bulk_ESS Tail_ESS
sd(logn2o_Intercept) 4413 4624
sd(logn2o_mono3_cat) 1412 2265
sd(logn2oeq_Intercept) 4061 6633
sd(sigma_logn2o_Intercept) 2790 4064
sd(sigma_logn2oeq_Intercept) 2176 1898
cor(logn2o_Intercept,logn2o_mono3_cat) 5823 6525
cor(logn2o_Intercept,logn2oeq_Intercept) 4935 6214
cor(logn2o_mono3_cat,logn2oeq_Intercept) 4684 4770
~WSA9:state (Number of levels: 96)
Estimate Est.Error l-95% CI u-95% CI Rhat
sd(logn2o_Intercept) 0.046 0.014 0.016 0.072 1.001
sd(logn2o_mono3_cat) 0.097 0.024 0.053 0.146 1.001
sd(logn2oeq_Intercept) 0.033 0.003 0.027 0.040 1.001
sd(sigma_logn2o_Intercept) 0.207 0.088 0.024 0.369 1.007
sd(sigma_logn2oeq_Intercept) 0.285 0.056 0.177 0.395 1.002
cor(logn2o_Intercept,logn2o_mono3_cat) -0.265 0.284 -0.762 0.336 1.001
cor(logn2o_Intercept,logn2oeq_Intercept) 0.163 0.200 -0.232 0.559 1.005
cor(logn2o_mono3_cat,logn2oeq_Intercept) 0.266 0.209 -0.155 0.649 1.002
Bulk_ESS Tail_ESS
sd(logn2o_Intercept) 1323 1765
sd(logn2o_mono3_cat) 2612 2569
sd(logn2oeq_Intercept) 3321 5286
sd(sigma_logn2o_Intercept) 776 1082
sd(sigma_logn2oeq_Intercept) 2464 3702
cor(logn2o_Intercept,logn2o_mono3_cat) 1708 3060
cor(logn2o_Intercept,logn2oeq_Intercept) 960 1715
cor(logn2o_mono3_cat,logn2oeq_Intercept) 883 1843
~WSA9:state:size_cat (Number of levels: 352)
Estimate Est.Error l-95% CI u-95% CI Rhat
sd(logn2o_Intercept) 0.035 0.015 0.004 0.062 1.004
sd(logn2oeq_Intercept) 0.003 0.002 0.000 0.007 1.003
sd(sigma_logn2o_Intercept) 0.479 0.056 0.374 0.591 1.006
sd(sigma_logn2oeq_Intercept) 0.260 0.052 0.160 0.360 1.001
cor(logn2o_Intercept,logn2oeq_Intercept) 0.235 0.413 -0.658 0.872 1.002
Bulk_ESS Tail_ESS
sd(logn2o_Intercept) 819 1375
sd(logn2oeq_Intercept) 1569 3553
sd(sigma_logn2o_Intercept) 1318 3346
sd(sigma_logn2oeq_Intercept) 2326 3796
cor(logn2o_Intercept,logn2oeq_Intercept) 2950 5425
Population-Level Effects:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
logn2o_Intercept 2.380 0.055 2.273 2.487 1.001 4020 6632
sigma_logn2o_Intercept -1.596 0.097 -1.789 -1.408 1.002 4961 6145
logn2oeq_Intercept 3.116 0.051 3.019 3.218 1.000 6860 7546
sigma_logn2oeq_Intercept -1.922 0.374 -2.639 -1.179 1.000 7865 7774
logn2o_log_area 0.029 0.003 0.023 0.034 1.000 9054 8090
logn2o_surftemp -0.025 0.002 -0.029 -0.021 1.000 3996 7106
sigma_logn2o_log_area -0.095 0.020 -0.135 -0.055 1.001 6068 7491
logn2oeq_surftemp -0.042 0.002 -0.046 -0.039 1.000 7418 8290
logn2oeq_log_elev -0.080 0.008 -0.097 -0.065 1.000 6834 7865
logn2oeq_surftemp:log_elev 0.003 0.000 0.002 0.003 1.000 7339 7992
sigma_logn2oeq_surftemp -0.065 0.010 -0.085 -0.046 1.000 9671 8132
sigma_logn2oeq_log_elev -0.018 0.038 -0.096 0.054 1.000 6265 7038
logn2o_mono3_cat 0.026 0.127 -0.226 0.275 1.004 1971 3252
logn2o_mono3_cat:log_area -0.036 0.010 -0.054 -0.016 1.001 2602 4549
logn2o_mono3_cat:surftemp 0.014 0.006 0.003 0.026 1.004 1478 2416
sigma_logn2o_mono3_cat 0.246 0.036 0.179 0.321 1.001 4246 6738
Simplex Parameters:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS
logn2o_mono3_cat1[1] 0.026 0.024 0.001 0.089 1.001 4261
logn2o_mono3_cat1[2] 0.091 0.066 0.005 0.252 1.001 1875
logn2o_mono3_cat1[3] 0.250 0.146 0.034 0.615 1.002 2027
logn2o_mono3_cat1[4] 0.633 0.166 0.206 0.867 1.003 1411
logn2o_mono3_cat:log_area1[1] 0.060 0.041 0.005 0.161 1.000 4395
logn2o_mono3_cat:log_area1[2] 0.042 0.039 0.001 0.142 1.000 7129
logn2o_mono3_cat:log_area1[3] 0.297 0.161 0.047 0.681 1.000 5220
logn2o_mono3_cat:log_area1[4] 0.602 0.176 0.166 0.865 1.000 4431
logn2o_mono3_cat:surftemp1[1] 0.043 0.040 0.006 0.144 1.002 3541
logn2o_mono3_cat:surftemp1[2] 0.080 0.056 0.015 0.222 1.001 3667
logn2o_mono3_cat:surftemp1[3] 0.276 0.111 0.105 0.573 1.001 3634
logn2o_mono3_cat:surftemp1[4] 0.601 0.142 0.168 0.785 1.002 2731
sigma_logn2o_mono3_cat1[1] 0.131 0.074 0.010 0.288 1.000 6840
sigma_logn2o_mono3_cat1[2] 0.151 0.096 0.010 0.367 1.000 7630
sigma_logn2o_mono3_cat1[3] 0.444 0.149 0.149 0.734 1.001 6331
sigma_logn2o_mono3_cat1[4] 0.275 0.138 0.026 0.544 1.001 4902
Tail_ESS
logn2o_mono3_cat1[1] 5305
logn2o_mono3_cat1[2] 3916
logn2o_mono3_cat1[3] 2856
logn2o_mono3_cat1[4] 2439
logn2o_mono3_cat:log_area1[1] 3509
logn2o_mono3_cat:log_area1[2] 6046
logn2o_mono3_cat:log_area1[3] 5683
logn2o_mono3_cat:log_area1[4] 4505
logn2o_mono3_cat:surftemp1[1] 3002
logn2o_mono3_cat:surftemp1[2] 2580
logn2o_mono3_cat:surftemp1[3] 3352
logn2o_mono3_cat:surftemp1[4] 2289
sigma_logn2o_mono3_cat1[1] 4269
sigma_logn2o_mono3_cat1[2] 5795
sigma_logn2o_mono3_cat1[3] 6964
sigma_logn2o_mono3_cat1[4] 5797
Residual Correlations:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
rescor(logn2o,logn2oeq) 0.141 0.038 0.066 0.216 1.000 11829 8204
Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
and Tail_ESS are effective sample size measures, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).
Model checks
Again, the same PPCs as above were performed for this model. #### N2O
PPC This PPC for N2O looked similar to the previous model.

Equilibrium
N2O
Again, the PPCs for this model were similar to the previous model,
which was unsurprising given that it was the same model for N2O-eq.

Bivariate
This PPC was also similar to the previous model.

Saturation
This check was also similar to the prevoius model, with perhaps
slightly less bias in the proportion unsaturated estimates. There is
also a potentially concerning extreme prediction in the observed
vs predicted PPC.

R-square
Estimate Est.Error Q2.5 Q97.5
R2logn2o 0.629 0.03 0.563 0.68
Estimate Est.Error Q2.5 Q97.5
R2logn2oeq 0.874 0.005 0.864 0.882
Covariate
effects
N2O
The conditional effects plot for the covariate effects N2O suggested
a similar effect of NO3, but interesting interactions between NO3 and
lake area and NO3 and surface temperature. For lake area, the effect was
estimated to be larger and more negative at the highest levels of NO3;
and slightly negative at the lowest level of NO3. For surface
temperature, the effect was estimated to be largest and positive at the
highest level of NO3; and negative at the lowest level of NO3.

The estimated covariate effects on \(\sigma\) suggested a negative relationship
with log(area) and a positive relationship, again, with NO3.

Equilibrium
N2O
The estimated covariate effect on N2O remained largely the same as
estimated in the previous model.


A Final Model
As demonstrated above, models excluding the NO3 covariate
consistently resulted in poorer fits to to the observed dissolved N2O
data. Including surface temperature and elevation in the equilibrium N2O
part of the model resulted in substantially improved replication of key
aspects of the observed data. Likewise, added flexibility in the
distributional terms for both dissolved and equilibrium N2O led to
improvements.
To make inferences from this model for N2O in the population of
interest, however, the included covariates needed to be (1) fully
observed across that population or (2) their missingness needed to be
modeled. For the lake area and elevation covariates, data was
available for all lakes from previously compiled geospatial databases.
However, neither surface temperature or NO3 were observed for lakes
outside of the sample. They were partially observed with respect to the
target population. Their missingness needed to be accounted for in a
model. Therefore, a more complex model was constructed below that
included surface temperature and NO3 as additional responses conditioned
on the survey design variables and fully observed covariates. This
approach to inference for N2O was similar to a Bayesian structural
equation model (Merkle et al. 2021; Merkle and Rosseel
2018). The main details of the logical dependence structure
could be characterized as:
\[\begin{align}
\color{#1F449C}{\boldsymbol{N_2O_{diss}}} &=\sim Survey + Area +
\color{#F05039}{\boldsymbol{NO_3}} + \color{#EEBAB4}{\boldsymbol{Temp}}
\\
\color{#A8B6CC}{\boldsymbol{N_2O_{equil}}} &=\sim Survey + Elev +
\color{#EEBAB4}{\boldsymbol{Temp}}\\
\color{#F05039}{\boldsymbol{NO_3}} &=\sim Survey + Area +
\color{#EEBAB4}{\boldsymbol{Temp}} \\
\color{#EEBAB4}{\boldsymbol{Temp}} &=\sim Survey + Lat + Elev + Day
\end{align}\]
Variables in color text above were treated as partially observed with
respect to the population of interest (i.e., observed only in the
sample), whereas variables in black text were considered fully observed.
The partially observed variables, being dissolved and equilibrium N2O,
NO3, and surface temperature, were each modeled conditional on the
survey design variables and other partially and/or fully observed
covariates. This structural equation approach requires a more complex
set of post-processing steps compared to a typical MRP analysis. In
order to propagate estimates and uncertainty through the dependency
structure and make inferences, the fitted model was used to first
predict surface temperature in the target population, since it depended
only on the fully observed covariates. That predictive distribution was
then used alongside the relevant fully observed covariates to predict
NO3 in the target population. Finally, the predictive distributions for
termperature and NO3 were used to predict the N2O responses. These steps
were carried out in the “Predict to population” section to follow.
In the final model below, the submodel for surface temperature
assumed a Gamma distributed error distribution and the linear predictor
included the survey design variables, latitude, elevation, and julian
date. The shape parameter was also modeled as a function of latitude to
address increasing response variance along the latitudinal gradient. The
NO3 submodel was a cumulative logit formulation and the linear predictor
included all of the survey factors as well as surface temperature and
lake area.
The N2O and N2O-eq responses were each modeled with Gamma distributed
errors, but with the same covariate structure as in model 5. The same
structure was also employed for the shape terms in these responses,
corresponding to the \(\sigma\) terms
in the previous model. Though not shown in this document, the Gamma
error structure appeared to result in slightly better performance in the
predictive checks compared to the Gaussian errors in previous models.
This was primarily apparent in the saturation ratio checks, which may
have been more sensitive to model performance in the tails of the N2O
responses. Others have also indicated that the Gamma error distribution
can work well for dissolved N2O data (Webb et al.
2019).
Note that there was no residual correlation term for this model,
since the residuals are undefined for the Gamma and cumulative logit
models. Dropping the observation-level residual correlation term was
deemed a reasonable compromise that enabled modeling the missingness of
NO3, in particular. Nevertheless, the random intercepts again allowed
for potential correlations between responses at the group levels.
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/df_model.rda")
bf_n2o <- bf(n2o ~ mo(no3_cat) +
log_area +
surftemp +
mo(no3_cat):log_area +
mo(no3_cat):surftemp +
(mo(no3_cat) | a | WSA9) +
(mo(no3_cat) | b | WSA9:state) +
(1 | c | WSA9:state:size_cat),
shape ~ log_area +
mo(no3_cat) +
(1 | WSA9) +
(1 | WSA9:state) +
(1 | WSA9:state:size_cat),
family = Gamma(link = "log"))
bf_n2oeq <- bf(n2o_eq ~ surftemp +
log_elev +
surftemp:log_elev +
(1 | a | WSA9) +
(1 | b | WSA9:state) +
(1 | c | WSA9:state:size_cat),
shape ~ surftemp +
log_elev +
(1 | WSA9) +
(1 | WSA9:state) +
(1 | WSA9:state:size_cat),
family = Gamma(link = "log"))
bf_temp <- bf(surftemp ~ lat +
s(log_elev) +
s(jdate) +
(1 | a | WSA9) +
(1 | b | WSA9:state) +
(1 | c | WSA9:state:size_cat),
shape ~ lat,
family = Gamma(link = "log"))
bf_no3 <- bf(no3_cat ~ surftemp +
log_area +
(1 | a | WSA9) +
(1 | b | WSA9:state) +
(1 | c | WSA9:state:size_cat),
family = cumulative(link = "logit", threshold="flexible"))
priors <- c(
prior(normal(2, 1), class = "Intercept", resp = "n2o"),
prior(normal(0, 1), class = "b", resp = "n2o"),
prior(exponential(2), class = "sd", resp = "n2o"),
prior(normal(5, 4), class = "Intercept", dpar = "shape", resp = "n2o"),
prior(normal(0, 1), class = "b", dpar = "shape", resp = "n2o"),
prior(exponential(2), class = "sd", dpar = "shape", resp = "n2o"),
prior(normal(2, 1), class = "Intercept", resp = "n2oeq"),
prior(normal(0, 1), class = "b", resp = "n2oeq"),
prior(exponential(2), class = "sd", resp = "n2oeq"),
prior(normal(5, 4), class = "Intercept", dpar = "shape", resp = "n2oeq"),
prior(normal(0, 1), class = "b", dpar = "shape", resp = "n2oeq"),
prior(exponential(2), class = "sd", dpar = "shape", resp = "n2oeq"),
prior(normal(3, 1), class = "Intercept", resp = "surftemp"),
prior(normal(0, 1), class = "b", resp = "surftemp"),
prior(exponential(0.5), class = "sds", resp = "surftemp"),
prior(exponential(2), class = "sd", resp = "surftemp"),
prior(normal(5, 4), class = "Intercept", dpar = "shape", resp = "surftemp"),
prior(normal(0, 1), class = "b", dpar = "shape", resp = "surftemp"),
prior(normal(0, 3), class = "Intercept", resp = "no3cat"),
prior(normal(0, 1), class = "b", resp = "no3cat"),
prior(exponential(1), class = "sd", resp = "no3cat"),
prior(lkj(2), class = "cor")
)
n2o_mod6 <- brm(bf_n2o +
bf_n2oeq +
bf_temp +
bf_no3 +
set_rescor(rescor = FALSE),
data = df_model,
prior = priors,
control = list(adapt_delta = 0.975, max_treedepth = 14),
#sample_prior = "only",
save_pars = save_pars(all = TRUE),
seed = 85132,#14548,
#init = my_inits,
init_r = 0.5,
chains=4,
iter=5000,
cores=4)
save(n2o_mod6, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/n2o_mod6.rda")
Summarize fit
Below is a summary of the fitted parameters and MCMC diagnostics.
Family: MV(gamma, gamma, gamma, cumulative)
Links: mu = log; shape = log
mu = log; shape = log
mu = log; shape = log
mu = logit; disc = identity
Formula: n2o ~ mo(no3_cat) + log_area + surftemp + mo(no3_cat):log_area + mo(no3_cat):surftemp + (mo(no3_cat) | a | WSA9) + (mo(no3_cat) | b | WSA9:state) + (1 | c | WSA9:state:size_cat)
shape ~ log_area + mo(no3_cat) + (1 | WSA9) + (1 | WSA9:state) + (1 | WSA9:state:size_cat)
n2o_eq ~ surftemp + log_elev + surftemp:log_elev + (1 | a | WSA9) + (1 | b | WSA9:state) + (1 | c | WSA9:state:size_cat)
shape ~ surftemp + log_elev + (1 | WSA9) + (1 | WSA9:state) + (1 | WSA9:state:size_cat)
surftemp ~ lat + s(log_elev) + s(jdate) + (1 | a | WSA9) + (1 | b | WSA9:state) + (1 | c | WSA9:state:size_cat)
shape ~ lat
no3_cat ~ surftemp + log_area + (1 | a | WSA9) + (1 | b | WSA9:state) + (1 | c | WSA9:state:size_cat)
Data: df_model (Number of observations: 984)
Draws: 4 chains, each with iter = 5000; warmup = 2500; thin = 1;
total post-warmup draws = 10000
Priors:
b_n2o ~ normal(0, 1)
b_n2o_shape ~ normal(0, 1)
b_n2oeq ~ normal(0, 1)
b_n2oeq_shape ~ normal(0, 1)
b_no3cat ~ normal(0, 1)
b_surftemp ~ normal(0, 1)
b_surftemp_shape ~ normal(0, 1)
Intercept_n2o ~ normal(2, 1)
Intercept_n2o_shape ~ normal(5, 4)
Intercept_n2oeq ~ normal(2, 1)
Intercept_n2oeq_shape ~ normal(5, 4)
Intercept_no3cat ~ normal(0, 3)
Intercept_surftemp ~ normal(3, 1)
Intercept_surftemp_shape ~ normal(5, 4)
L ~ lkj_corr_cholesky(2)
<lower=0> sd_n2o ~ exponential(2)
<lower=0> sd_n2o_shape ~ exponential(2)
<lower=0> sd_n2oeq ~ exponential(2)
<lower=0> sd_n2oeq_shape ~ exponential(2)
<lower=0> sd_no3cat ~ exponential(1)
<lower=0> sd_surftemp ~ exponential(2)
<lower=0> sds_surftemp ~ exponential(0.5)
simo_n2o_mono3_cat:log_area1 ~ dirichlet(1)
simo_n2o_mono3_cat:surftemp1 ~ dirichlet(1)
simo_n2o_mono3_cat1 ~ dirichlet(1)
simo_n2o_shape_mono3_cat1 ~ dirichlet(1)
Smooth Terms:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
sds(surftemp_slog_elev_1) 1.161 0.370 0.638 2.079 1.001 2264 4174
sds(surftemp_sjdate_1) 0.571 0.277 0.226 1.273 1.000 2679 4853
Group-Level Effects:
~WSA9 (Number of levels: 9)
Estimate Est.Error l-95% CI u-95% CI Rhat
sd(n2o_Intercept) 0.048 0.018 0.020 0.091 1.000
sd(n2o_mono3_cat) 0.045 0.035 0.002 0.129 1.003
sd(n2oeq_Intercept) 0.033 0.011 0.018 0.061 1.000
sd(surftemp_Intercept) 0.031 0.014 0.011 0.064 1.001
sd(no3cat_Intercept) 0.690 0.256 0.296 1.308 1.000
sd(shape_n2o_Intercept) 0.211 0.141 0.011 0.535 1.000
sd(shape_n2oeq_Intercept) 0.402 0.183 0.075 0.814 1.001
cor(n2o_Intercept,n2o_mono3_cat) -0.049 0.336 -0.667 0.614 1.000
cor(n2o_Intercept,n2oeq_Intercept) 0.393 0.268 -0.202 0.824 1.000
cor(n2o_mono3_cat,n2oeq_Intercept) 0.102 0.328 -0.559 0.686 1.000
cor(n2o_Intercept,surftemp_Intercept) -0.350 0.296 -0.839 0.285 1.000
cor(n2o_mono3_cat,surftemp_Intercept) 0.089 0.333 -0.564 0.703 1.000
cor(n2oeq_Intercept,surftemp_Intercept) -0.167 0.299 -0.705 0.437 1.000
cor(n2o_Intercept,no3cat_Intercept) -0.057 0.295 -0.605 0.522 1.000
cor(n2o_mono3_cat,no3cat_Intercept) 0.141 0.333 -0.539 0.724 1.002
cor(n2oeq_Intercept,no3cat_Intercept) 0.272 0.274 -0.305 0.740 1.001
cor(surftemp_Intercept,no3cat_Intercept) 0.185 0.300 -0.436 0.718 1.000
Bulk_ESS Tail_ESS
sd(n2o_Intercept) 3011 2931
sd(n2o_mono3_cat) 1540 3502
sd(n2oeq_Intercept) 3147 4572
sd(surftemp_Intercept) 3705 4498
sd(no3cat_Intercept) 4184 5618
sd(shape_n2o_Intercept) 2379 3641
sd(shape_n2oeq_Intercept) 2208 1617
cor(n2o_Intercept,n2o_mono3_cat) 6558 6134
cor(n2o_Intercept,n2oeq_Intercept) 4604 6010
cor(n2o_mono3_cat,n2oeq_Intercept) 3241 5029
cor(n2o_Intercept,surftemp_Intercept) 4744 5916
cor(n2o_mono3_cat,surftemp_Intercept) 5246 6447
cor(n2oeq_Intercept,surftemp_Intercept) 7342 7508
cor(n2o_Intercept,no3cat_Intercept) 5152 6479
cor(n2o_mono3_cat,no3cat_Intercept) 3435 5897
cor(n2oeq_Intercept,no3cat_Intercept) 6449 7400
cor(surftemp_Intercept,no3cat_Intercept) 6490 7928
~WSA9:state (Number of levels: 96)
Estimate Est.Error l-95% CI u-95% CI Rhat
sd(n2o_Intercept) 0.047 0.013 0.021 0.072 1.004
sd(n2o_mono3_cat) 0.101 0.019 0.068 0.142 1.001
sd(n2oeq_Intercept) 0.033 0.003 0.026 0.040 1.001
sd(surftemp_Intercept) 0.035 0.006 0.023 0.047 1.000
sd(no3cat_Intercept) 0.878 0.128 0.649 1.147 1.000
sd(shape_n2o_Intercept) 0.383 0.178 0.032 0.707 1.004
sd(shape_n2oeq_Intercept) 0.561 0.114 0.336 0.781 1.002
cor(n2o_Intercept,n2o_mono3_cat) -0.145 0.254 -0.602 0.376 1.002
cor(n2o_Intercept,n2oeq_Intercept) 0.183 0.189 -0.180 0.549 1.003
cor(n2o_mono3_cat,n2oeq_Intercept) 0.201 0.164 -0.122 0.519 1.002
cor(n2o_Intercept,surftemp_Intercept) -0.023 0.237 -0.476 0.438 1.004
cor(n2o_mono3_cat,surftemp_Intercept) -0.232 0.215 -0.644 0.194 1.001
cor(n2oeq_Intercept,surftemp_Intercept) -0.134 0.190 -0.494 0.246 1.000
cor(n2o_Intercept,no3cat_Intercept) 0.462 0.211 0.018 0.822 1.004
cor(n2o_mono3_cat,no3cat_Intercept) 0.145 0.200 -0.251 0.531 1.000
cor(n2oeq_Intercept,no3cat_Intercept) 0.054 0.140 -0.220 0.329 1.000
cor(surftemp_Intercept,no3cat_Intercept) -0.231 0.189 -0.586 0.154 1.001
Bulk_ESS Tail_ESS
sd(n2o_Intercept) 1025 1337
sd(n2o_mono3_cat) 3366 4975
sd(n2oeq_Intercept) 2809 4611
sd(surftemp_Intercept) 4124 5116
sd(no3cat_Intercept) 4389 6247
sd(shape_n2o_Intercept) 649 1304
sd(shape_n2oeq_Intercept) 1908 1810
cor(n2o_Intercept,n2o_mono3_cat) 1069 1955
cor(n2o_Intercept,n2oeq_Intercept) 794 1260
cor(n2o_mono3_cat,n2oeq_Intercept) 833 1873
cor(n2o_Intercept,surftemp_Intercept) 1849 3618
cor(n2o_mono3_cat,surftemp_Intercept) 2626 4267
cor(n2oeq_Intercept,surftemp_Intercept) 6340 6860
cor(n2o_Intercept,no3cat_Intercept) 893 1944
cor(n2o_mono3_cat,no3cat_Intercept) 1746 3085
cor(n2oeq_Intercept,no3cat_Intercept) 6378 7983
cor(surftemp_Intercept,no3cat_Intercept) 3573 5949
~WSA9:state:size_cat (Number of levels: 352)
Estimate Est.Error l-95% CI u-95% CI Rhat
sd(n2o_Intercept) 0.038 0.014 0.006 0.064 1.011
sd(n2oeq_Intercept) 0.004 0.002 0.000 0.008 1.009
sd(surftemp_Intercept) 0.010 0.007 0.000 0.024 1.003
sd(no3cat_Intercept) 0.308 0.182 0.016 0.673 1.002
sd(shape_n2o_Intercept) 0.895 0.110 0.684 1.114 1.002
sd(shape_n2oeq_Intercept) 0.511 0.104 0.309 0.715 1.002
cor(n2o_Intercept,n2oeq_Intercept) 0.310 0.349 -0.486 0.841 1.004
cor(n2o_Intercept,surftemp_Intercept) 0.015 0.365 -0.677 0.705 1.000
cor(n2oeq_Intercept,surftemp_Intercept) -0.102 0.381 -0.761 0.659 1.001
cor(n2o_Intercept,no3cat_Intercept) -0.090 0.342 -0.716 0.601 1.001
cor(n2oeq_Intercept,no3cat_Intercept) -0.143 0.359 -0.757 0.611 1.001
cor(surftemp_Intercept,no3cat_Intercept) 0.173 0.378 -0.599 0.807 1.001
Bulk_ESS Tail_ESS
sd(n2o_Intercept) 580 1036
sd(n2oeq_Intercept) 1062 3160
sd(surftemp_Intercept) 1917 3889
sd(no3cat_Intercept) 1078 2386
sd(shape_n2o_Intercept) 1068 2786
sd(shape_n2oeq_Intercept) 1397 2071
cor(n2o_Intercept,n2oeq_Intercept) 2099 4705
cor(n2o_Intercept,surftemp_Intercept) 4876 6414
cor(n2oeq_Intercept,surftemp_Intercept) 4195 5741
cor(n2o_Intercept,no3cat_Intercept) 3188 5334
cor(n2oeq_Intercept,no3cat_Intercept) 2749 4946
cor(surftemp_Intercept,no3cat_Intercept) 2607 5750
Population-Level Effects:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
n2o_Intercept 2.392 0.056 2.285 2.500 1.000 3063 5517
shape_n2o_Intercept 3.215 0.189 2.849 3.589 1.001 3997 6108
n2oeq_Intercept 3.111 0.053 3.011 3.218 1.000 5146 6075
shape_n2oeq_Intercept 3.873 0.751 2.385 5.326 1.001 5619 6535
surftemp_Intercept 3.791 0.060 3.672 3.906 1.000 7414 7632
shape_surftemp_Intercept 8.637 0.460 7.721 9.522 1.001 10817 7718
no3cat_Intercept[1] -3.025 0.615 -4.258 -1.864 1.000 5932 6622
no3cat_Intercept[2] -2.059 0.605 -3.274 -0.903 1.000 6278 6695
no3cat_Intercept[3] -1.027 0.600 -2.235 0.115 1.000 6689 6957
no3cat_Intercept[4] -0.028 0.602 -1.247 1.113 1.000 7002 6940
n2o_log_area 0.028 0.003 0.022 0.034 1.000 6958 7668
n2o_surftemp -0.025 0.002 -0.029 -0.021 1.000 3145 6260
shape_n2o_log_area 0.190 0.041 0.110 0.271 1.000 4322 5605
n2oeq_surftemp -0.042 0.002 -0.045 -0.038 1.000 5836 6494
n2oeq_log_elev -0.080 0.008 -0.097 -0.064 1.000 5425 6234
n2oeq_surftemp:log_elev 0.002 0.000 0.002 0.003 1.000 5857 6696
shape_n2oeq_surftemp 0.131 0.020 0.092 0.171 1.001 6725 7112
shape_n2oeq_log_elev 0.030 0.077 -0.117 0.186 1.001 4914 6636
surftemp_lat -0.016 0.001 -0.019 -0.013 1.000 7349 7598
shape_surftemp_lat -0.105 0.011 -0.127 -0.083 1.000 11330 7919
no3cat_surftemp -0.141 0.023 -0.187 -0.096 1.001 6713 7328
no3cat_log_area 0.068 0.035 -0.001 0.137 1.000 11692 8177
surftemp_slog_elev_1 -3.477 0.479 -4.414 -2.557 1.000 5891 6330
surftemp_sjdate_1 -0.008 0.528 -1.074 1.017 1.000 4010 5523
n2o_mono3_cat 0.007 0.087 -0.172 0.175 1.004 1650 1855
n2o_mono3_cat:log_area -0.046 0.009 -0.063 -0.027 1.001 2079 2821
n2o_mono3_cat:surftemp 0.018 0.004 0.009 0.026 1.004 1417 1621
shape_n2o_mono3_cat -0.510 0.070 -0.649 -0.375 1.001 4691 6283
Simplex Parameters:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
n2o_mono3_cat1[1] 0.025 0.023 0.001 0.083 1.000 4899 5237
n2o_mono3_cat1[2] 0.183 0.111 0.014 0.425 1.002 1056 3343
n2o_mono3_cat1[3] 0.408 0.158 0.103 0.725 1.002 2167 4583
n2o_mono3_cat1[4] 0.384 0.169 0.058 0.713 1.003 1608 3021
n2o_mono3_cat:log_area1[1] 0.046 0.029 0.003 0.112 1.000 4018 3309
n2o_mono3_cat:log_area1[2] 0.033 0.028 0.001 0.104 1.001 6173 4948
n2o_mono3_cat:log_area1[3] 0.289 0.134 0.057 0.598 1.000 3286 4461
n2o_mono3_cat:log_area1[4] 0.631 0.140 0.301 0.864 1.000 3186 4184
n2o_mono3_cat:surftemp1[1] 0.028 0.019 0.003 0.060 1.001 3744 3410
n2o_mono3_cat:surftemp1[2] 0.066 0.033 0.011 0.128 1.001 3821 3213
n2o_mono3_cat:surftemp1[3] 0.281 0.079 0.122 0.431 1.003 2897 2971
n2o_mono3_cat:surftemp1[4] 0.625 0.088 0.461 0.798 1.003 2740 3106
shape_n2o_mono3_cat1[1] 0.116 0.067 0.009 0.263 1.001 5363 4297
shape_n2o_mono3_cat1[2] 0.149 0.096 0.008 0.365 1.001 3469 3637
shape_n2o_mono3_cat1[3] 0.401 0.151 0.116 0.703 1.001 4122 5848
shape_n2o_mono3_cat1[4] 0.334 0.143 0.051 0.604 1.001 3853 4561
Family Specific Parameters:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
disc_no3cat 1.000 0.000 1.000 1.000 NA NA NA
Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
and Tail_ESS are effective sample size measures, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).
Model checks
Below, the same PPCs for N2O and N2O-eq were employed as before. ####
N2O PPC The PPCs for N2O from this model were similarly reasonable as
for models 4 and 5 above.
Using all posterior draws for ppc type 'stat_2d' by default.
Using all posterior draws for ppc type 'stat_2d' by default.
Using all posterior draws for ppc type 'stat_2d' by default.
Using all posterior draws for ppc type 'scatter_avg' by default.

Equilibrium N2O
PPC
Again, the PPCs for N2O-eq in this model were similar to those for
models 4 and 5.
Using all posterior draws for ppc type 'stat_2d' by default.
Using all posterior draws for ppc type 'stat_2d' by default.
Using all posterior draws for ppc type 'stat_2d' by default.
Using all posterior draws for ppc type 'scatter_avg' by default.

Bivariate
PPC
This model again provided a very reasonable representation of the
bivariate relationship between N2O and N2O-eq (below).

Saturation
PPC
The saturation ratio PPCs below show similar behavior as with models
4 and 5 above, but with perhaps slightly less bias in the predictions
for the proportion of undersaturated waterbodies and fewer extreme
predictions for the means and standard deviations. The observed
vs. predicted PPC also appears to have a better behaved
variance and no extreme predictions, compared to models 4 and 5 with the
lognormal errors.

The plot below shows the same PPC, but for the “test” or second-vist
data. Overall, the model looked to perform similarly as with the data
used to fit it.

R-square
Below are estimates for the Bayesian \(R^2\), which were largely similar for N2O
and N2O-eq as with models 4 and 5 above. The \(R^2\) for the surface temperature response
also suggested a fairly good fit.
Estimate Est.Error Q2.5 Q97.5
R2n2o 0.646 0.059 0.503 0.731
Estimate Est.Error Q2.5 Q97.5
R2n2oeq 0.863 0.006 0.851 0.874
Estimate Est.Error Q2.5 Q97.5
R2surftemp 0.744 0.01 0.723 0.763
Below are the same \(R^2\)
estimates, but for the second-visit data. That these estimates are
similar to those for the data used to fit the model, suggesting that the
model may perform similarly well out-of-sample.
Estimate Est.Error Q2.5 Q97.5
R2n2o 0.607 0.137 0.325 0.85
Estimate Est.Error Q2.5 Q97.5
R2n2oeq 0.857 0.008 0.84 0.872
Estimate Est.Error Q2.5 Q97.5
R2surftemp 0.75 0.018 0.715 0.783
Covariate
effects
N2O
The conditional effects plot for the covariate effects N2O suggested
a similar effect of NO3, but interesting interactions between NO3 and
lake area and NO3 and surface temperature. For lake area, the effect was
estimated to be larger and more negative at the highest levels of NO3;
and slightly negative at the lowest level of NO3. For surface
temperature, the effect was estimated to be largest and positive at the
highest level of NO3; and negative at the lowest level of NO3.

The estimated covariate effects on \(\sigma\) suggested a negative relationship
with log(area) and a positive relationship, again, with NO3.

Equilibrium
N2O
The estimated covariate effect on N2O remained largely the same as
estimated in the previous model.


Predict to
population
As previously described, in order to make inferences to the
population of interest, the final model above was used to, first,
predict surface temperature in the target population, since it depended
only on the fully observed covariates. Next, the predictive distribution
for surface temperature was used, along with the relevant fully observed
covariates, to predict NO3 in the target population. Finally, the
predictive distributions for temperature and NO3 were used to predict
the N2O responses. The code for these steps is outlined in the
following.
The first step used the final model to predict to the population:
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/sframe.rda")
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/n2o_mod6.rda")
predict_temp <- sframe %>%
mutate(jdate = 205) %>%
add_predicted_draws(n2o_mod6, resp=c("surftemp"),
allow_new_levels = TRUE,
cores =1,
ndraws = 500) %>%
mutate(surftemp = .prediction)
save(predict_temp, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/predict_temp.rda")
NO3 was next predicted. Note that the posterior predictive
distribution for NO3 was subsampled in order to minimize excess
simulations
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/n2o_mod6.rda")
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/predict_temp.rda")
temp_X <- predict_temp %>% # select relevant columns as predictors
ungroup() %>%
select(WSA9,
state,
size_cat,
log_area,
.row,
.draw,
surftemp) %>%
select(WSA9, state, size_cat, log_area, surftemp)
rm(predict_temp) # reduce memory
gc()
# set number of cores to use for parallel predictions
# and register the workers
cl <- parallel::makeCluster(5)
doSNOW::registerDoSNOW(cl)
# make a progress bar
pb <- txtProgressBar(max = 1500, style = 3)
progress <- function(n) setTxtProgressBar(pb, n)
opts <- list(progress = progress)
system.time( # approx 26 hrs with 5 workers & 500 draws from PPD
predict_no3 <- foreach(sub_X = isplitRows(temp_X, chunkSize = 155299),
.combine = 'c',
.packages = c("brms"),
.options.snow = opts
) %dopar% {
apply(brms::posterior_predict(n2o_mod6,
newdata = sub_X,
resp = "no3cat",
allow_new_levels = T,
ndraws = 500,
cores = 1), 2, sample, 1)
}
)
close(pb)
parallel::stopCluster(cl)
save(predict_no3, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/predict_no3.rda")
Finally, N2O and N2O-eq were predicted using the surface temperature
and nitrate predictions along with the survey variables and known
covariates. Again, the posterior was subsampled in order to reduce
excess simulations.
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/predict_no3.rda")
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/predict_temp.rda")
# Assemble dataframe containing relevant covariates (known and predicted)
n2o_X <- predict_temp %>%
ungroup() %>%
mutate(no3_cat = predict_no3) %>%
select(WSA9,
state,
size_cat,
log_area,
surftemp,
log_elev,
no3_cat)
# clear objects to reduce memory overhead
rm(predict_no3, predict_temp)
gc()
# save the predictors for n2o and n2oeq
save(n2o_X, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/n2o_X.rda")
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/n2o_mod6.rda")
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/n2o_X.rda")
# set number of cores to use for parallel predictions
# and register the workers
cl <- parallel::makeCluster(6)
doSNOW::registerDoSNOW(cl)
# make a progress bar
pb <- txtProgressBar(max = 1500, style = 3)
progress <- function(n) setTxtProgressBar(pb, n)
opts <- list(progress = progress)
# make predictions in parallel
system.time(
predict_n2o <- foreach(sub_X = isplitRows(n2o_X, chunkSize = 155299),
.combine = rbind,
.options.snow = opts,
.packages = c("brms")) %dopar% {
apply(posterior_predict(n2o_mod6,
newdata = sub_X,
resp = c("n2o", "n2oeq"),
allow_new_levels = T,
ndraws = 500,
cores = 1),
2, sample, 1)
}
)
close(pb)
parallel::stopCluster(cl)
colnames(predict_n2o) <- c("n2o", "n2oeq")
save(predict_n2o, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/predict_n2o.rda")
Finally, the predictions for all four partially observed responses
were assembled into a new dataframe for use in inference.
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/predict_n2o.rda")
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/predict_no3.rda")
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/predict_temp.rda")
all_predictions <- predict_temp %>%
ungroup() %>%
mutate(no3cat = predict_no3) %>%
bind_cols(predict_n2o) %>%
mutate(n2osat = n2o / n2oeq, # calculate saturation ratio
.row = rep(1:465897, each = 500),
.draw = rep(seq(1,500, 1), 465897)) %>%
mutate(area_ha = exp(log_area)) %>% # include area on ha scale
select(WSA9,
state,
size_cat,
area_ha,
lat,
lon,
.row,
.draw,
surftemp,
no3cat,
n2o,
n2oeq,
n2osat)
rm(predict_n2o, predict_temp, predict_no3) # clean up workspace for RAM
gc()
save(all_predictions, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/all_predictions.rda")
LS0tDQp0aXRsZTogIkJheWVzaWFuIG1vZGVscyBmb3IgTkxBIDIwMTcgJE5fMk8kIHN1cnZleSBkYXRhIg0KYXV0aG9yOiAiUm95IE1hcnRpbiwgSmFrZSBCZWF1bGlldSwgTWljaGFlbCBNY01hbnVzIg0KZGF0ZTogImByIFN5cy5EYXRlKClgIg0Kb3V0cHV0Og0KICBwZGZfZG9jdW1lbnQ6DQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6ICc0Jw0KICBodG1sX25vdGVib29rOg0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cNCiAgICBmb250X3NpemU6IDE0DQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0aGVtZTogc2ltcGxleA0KICBnaXRodWJfZG9jdW1lbnQ6DQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIGNvZGVfZm9sZGluZzogc2hvdw0KICAgIGZvbnRfc2l6ZTogMTQNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIHRoZW1lOiBzaW1wbGV4DQpiaWJsaW9ncmFwaHk6IFJXTV9FbmRub3RlX0xpYnJhcnkuYmliDQpsaW5rLWNpdGF0aW9uczogeWVzDQplZGl0b3Jfb3B0aW9uczoNCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQ0KLS0tDQoNCmBgYHtyIGJlZ2luLCBldmFsPVRSVUUsIGluY2x1ZGU9RkFMU0V9DQpsaWJyYXJ5KGdncHVicikNCmxpYnJhcnkobW9tZW50cykNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZ2dFeHRyYSkNCmxpYnJhcnkoZ3JpZEV4dHJhKQ0KbGlicmFyeShrYWJsZUV4dHJhKQ0KbGlicmFyeShnZ3JlcGVsKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeSh0aWR5cikNCmxpYnJhcnkoZnV0dXJlKQ0KbGlicmFyeShmb3JlYWNoKQ0KbGlicmFyeShpdGVydG9vbHMpDQpsaWJyYXJ5KGJheWVzcGxvdCkNCmxpYnJhcnkodGlkeWJheWVzKQ0KbGlicmFyeShicm1zKQ0KDQpvcHRpb25zKG1jLmNvcmVzID0gcGFyYWxsZWw6OmRldGVjdENvcmVzKGxvZ2ljYWwgPSBGQUxTRSkpDQpvcHRpb25zKCBtYXgucHJpbnQgPSAxMDAwICkNCg0KIyBJZGVudGlmeSBsb2NhbCBwYXRoIGZvciBlYWNoIHVzZXINCmxvY2FsUGF0aCA8LSBTeXMuZ2V0ZW52KCJVU0VSUFJPRklMRSIpDQoNCiMgRGVmaW5lIGhlbHBlciBmdW5jdGlvbnMNCiMgc3RhbmRhcmRpemVkIGZvcm1hdHRpbmcgZm9yIGNvbHVtbiBuYW1lcw0KdG9FUEEgPC0gZnVuY3Rpb24oWDEpew0KICBuYW1lcyhYMSkgPSB0b2xvd2VyKG5hbWVzKFgxKSkNCiAgbmFtZXMoWDEpID0gZ3N1YihwYXR0ZXJuID0gYygiXFwofCB8I3wpfC98LXxcXCt8OnxfIiksIHJlcGxhY2VtZW50ID0gIi4iLCB4ID0gbmFtZXMoWDEpKQ0KICBYMQ0KfQ0KDQojIHN0YXQ6IHNrZXcgDQpza2V3IDwtIGZ1bmN0aW9uKHgpIHsNCiAgeGRldiA8LSB4IC0gbWVhbih4KQ0KICBuIDwtIGxlbmd0aCh4KQ0KICByIDwtIHN1bSh4ZGV2XjMpIC8gc3VtKHhkZXZeMileMS41DQogIHJldHVybihyICogc3FydChuKSAqICgxIC0gMS9uKV4xLjUpDQp9DQoNCiMgZnVuY3Rpb24gZm9yIERIQVJNYSByZXNpZHVhbCBhbmFseXNpcw0KY2hlY2tfYnJtcyA8LSBmdW5jdGlvbihtb2RlbCwgICAgICAgICAgICAgIyBicm1zIG1vZGVsDQogICAgICAgICAgICAgICAgICAgICAgIGludGVnZXIgPSBGQUxTRSwgICAjIGludGVnZXIgcmVzcG9uc2U/IChUUlVFL0ZBTFNFKQ0KICAgICAgICAgICAgICAgICAgICAgICBwbG90ID0gVFJVRSwgICAgICAgIyBtYWtlIHBsb3Q/DQogICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSBOVUxMLA0KICAgICAgICAgICAgICAgICAgICAgICAuLi4gICAgICAgICAgICAgICAgIyBmdXJ0aGVyIGFyZ3VtZW50cyBmb3IgREhBUk1hOjpwbG90UmVzaWR1YWxzIA0KKSB7DQogIA0KICBtZGF0YSA8LSBicm1zOjpzdGFuZGF0YShtb2RlbCkNCiAgaWYoISJZIiAlaW4lIG5hbWVzKG1kYXRhKSkNCiAgICBvUmVzcCA8LSBtZGF0YVtbcGFzdGUwKCJZXyIsIHJlc3ApXV0NCiAgZWxzZQ0KICAgIG9SZXNwIDwtIG1kYXRhW1siWSJdXQ0KICAjICBzdG9wKCJDYW5ub3QgZXh0cmFjdCB0aGUgcmVxdWlyZWQgaW5mb3JtYXRpb24gZnJvbSB0aGlzIGJybXMgbW9kZWwiKQ0KICANCiAgZGhhcm1hLm9iaiA8LSBESEFSTWE6OmNyZWF0ZURIQVJNYSgNCiAgICBzaW11bGF0ZWRSZXNwb25zZSA9IHQoYnJtczo6cG9zdGVyaW9yX3ByZWRpY3QobW9kZWwsIHJlc3AgPSByZXNwLCBuZHJhd3MgPSAxMDAwKSksDQogICAgb2JzZXJ2ZWRSZXNwb25zZSA9IG9SZXNwLCANCiAgICBmaXR0ZWRQcmVkaWN0ZWRSZXNwb25zZSA9IGFwcGx5KA0KICAgICAgdChicm1zOjpwb3N0ZXJpb3JfZXByZWQobW9kZWwsIHJlc3AgPSByZXNwLCBuZHJhd3MgPSAxMDAwLCByZS5mb3JtID0gTkEpKSwNCiAgICAgIDEsDQogICAgICBtZWRpYW4pLA0KICAgIGludGVnZXJSZXNwb25zZSA9IGludGVnZXIpDQogIA0KICBpZiAoaXNUUlVFKHBsb3QpKSB7DQogICAgcGxvdChkaGFybWEub2JqLCAuLi4pDQogIH0NCiAgDQogIGludmlzaWJsZShkaGFybWEub2JqKQ0KICANCn0NCmBgYA0KDQojIFJhdGlvbmFsZSBhbmQgT2JqZWN0aXZlcw0KVGhpcyBkb2N1bWVudCBkZXRhaWxzIHRoZSBtb2RlbGluZyB3b3JrZmxvdyBpbXBsZW1lbnRlZCBmb3IgZXN0aW1hdGluZyBkaXNzb2x2ZWQgYW5kIGVxdWlsaWJyaXVtIE4yTyBjb25jZW50cmF0aW9ucyBhbmQgc2F0dXJhdGlvbiByYXRpb3MgdXNpbmcgdGhlIDIwMTcgTmF0aW9uIExha2VzIEFzc2Vzc21lbnQgKE5MQSkgc3VydmV5IGRhdGEuIFRoZSBOTEEgc2FtcGxpbmcgc2l0ZXMgd2VyZSBkaXN0cmlidXRlZCBhbW9uZyB0aGUgdGFyZ2V0IHBvcHVsYXRpb24gb2YgVVMgbGFrZXMgKGluIHRoZSBsb3dlciA0OCBzdGF0ZXMpIGFjY29yZGluZyB0byBhIHByb2JhYmlsaXN0aWMgc3VydmV5IGRlc2lnbiB3aXRoIHNhbXBsZXMgc3RyYXRpZmllZCBhbW9uZyBjYXRlZ29yaWVzIG9mIGxha2Ugc3VyZmFjZSBhcmVhLCBXU0E5IGVjb3JlZ2lvbiwgYW5kIFVTIHN0YXRlIChleGNsdWRpbmcgQUsgYW5kIEhJKS4gRHVlIHRvIHRoZSBzdHJhdGlmaWNhdGlvbiBzY2hlbWUsIHNvbWUgdHlwZXMgb2YgbGFrZXMgaW4gdGhlIHNhbXBsZSBwb3B1bGF0aW9uIHdlcmUgaW50ZW50aW9uYWxseSBvdmVyLXJlcHJlc2VudGVkIChlLmcuLCBsYXJnZSBsYWtlcykgYW5kIHNvbWUgd2VyZSB1bmRlci1yZXByZXNlbnRlZCAoZS5nLiwgc21hbGwgbGFrZXMpIHJlbGF0aXZlIHRvIHRoZSB0YXJnZXQgcG9wdWxhdGlvbi4gRHVlIHRvIHRoZSB1bmVxdWFsIHByb2JhYmlsaXR5IGRlc2lnbiwgaW5mZXJlbmNlcyBmcm9tIHRoZSBzYW1wbGUgaGFkIHRvIGJlIGFkanVzdGVkIGZvciBpbmZlcmVuY2VzIG9uIHRoZSBicm9hZGVyIHBvcHVsYXRpb25zIG9mIGludGVyZXN0IChlLmcsIE5hdGlvbmFsLSwgc3RhdGUtLCBlY29yZWdpb24tLCBhbmQgc2l6ZSBjbGFzcy1zcGVjaWZpYyBlc3RpbWF0ZXMpLiANCg0KVGhlIGNvbmNlcHQgb2YgdGhlICJjb21wbGV0ZSBkYXRhIGxpa2VsaWhvb2QiIGlzIHVzZWZ1bCBmb3IgY29uY2VwdHVhbGl6aW5nIGJpYXNlcyBhcmlzaW5nIGZyb20gc2FtcGxpbmcgZGVzaWduIFtAWmFjaG1hbm5fZXRhbF8yMDIyOyBAR2VsbWFuX2V0YWxfMjAxNCBDaC4gODsgQExpbmtfQmFya2VyXzIwMTBdLiBGb3IgdGhlIE5MQSBzdXJ2ZXkgZGF0YSwgdGhlIHBvcHVsYXRpb24gb2YgVVMgbGFrZXMgaW4gdGhlIGxvd2VyIDQ4IHN0YXRlcyBsYXJnZXIgdGhhbiA0IGhlY3RhcmVzIHdhcyBjb25zaWRlcmVkIHRoZSBjb21wbGV0ZSBkYXRhIGFuZCB0aGUgcHJvYmFiaWxpc3RpYyBzYW1wbGVzIHdlcmUgY29uc2lkZXJlZCBhIHN1YnNldCBvZiB0aGF0IGNvbXBsZXRlIGRhdGEuIFRoZSBwb3J0aW9uIG9mIFVTIGxha2VzIG5vdCBpbmNsdWRlZCBpbiB0aGUgc2FtcGxlIHdlcmUgY29uc2lkZXJlZCAibWlzc2luZyIgZnJvbSB0aGUgY29tcGxldGUgZGF0YSBfbm90XyBhdCByYW5kb20sIGJ1dCBjb25kaXRpb25hbCBvbiB0aGUgcHJlLXNwZWNpZmllZCBkZXNpZ24gKHN0cmF0aWZpY2F0aW9uKSB2YXJpYWJsZXMuIFRoaXMgbm9uLXJhbmRvbSBtaXNzaW5nbmVzcyB3YXMgbm90IGlnbm9yYWJsZSBmb3IgdGhlIHB1cnBvc2Ugb2YgbWFraW5nIGluZmVyZW5jZXMgZnJvbSB0aGUgc2FtcGxlIHRvIHRoZSB0YXJnZXQgcG9wdWxhdGlvbi4gSW4gYSBtb2RlbC1iYXNlZCBmcmFtZXdvcmssIGhvd2V2ZXIsIGluY2x1ZGluZyB0aGUgZGVzaWduIHBhcmFtZXRlcnMgYXMgcHJlZGljdG9ycyBpbiBhIHJlZ3Jlc3Npb24gbW9kZWwgaXMgb25lIHdheSB0byBhZGp1c3QgZm9yIHRoZSBtaXNzaW5nbmVzcy4gRm9yIGEgdGhvcm91Z2ggYW5kIHJlY2VudCB0cmVhdG1lbnQgb2YgdGhpcyBjb25jZXB0IGluIHRoZSBjb250ZXh0IG9mIG5hdGlvbmFsIHN1cnZleXMgb2YgZW52aXJvbm1lbnRhbCByZXNvdXJjZXMsIHJlZmVyIHRvIFtAWmFjaG1hbm5fZXRhbF8yMDIyXS4gVGhpcyBjb25jZXB0IGlzIGEga2V5IG1vdGl2YXRvciBmb3IgdGhlIGluY3JlYXNpbmdseSBwb3B1bGFyIG11bGl0aWxldmVsIHJlZ3Jlc3Npb24gd2l0aCBwb3N0c3RyYXRpZmljYXRpb24gKE1SUCkgYXBwcm9hY2ggdG8gbW9kZWwtYmFzZWQgaW5mZXJlbmNlIFtAR2VsbWFuX2V0YWxfMjAxNDsgR2VsbWFudF9ldGFsXzIwMjAgQ2guIDE3XS4NCg0KVGhlIGZvbGxvd2luZyB3b3JrZmxvdyBpbGx1c3RyYXRlcyBvdXIgbW9kZWwtYmFzZWQgYXBwcm9hY2gsIGJhc2VkIGxhcmdlbHkgb24gdGhlIGxvZ2ljIG9mIE1SUCwgYnV0IHdpdGggYW4gZWxhYm9yYXRpb24gb24gdGhlIHBvc3RzdHJhdGlmaWNhdGlvbiBzdGVwIHRvIGVuYWJsZSBldmVudHVhbCBlc3RpbWF0ZXMgb2YgdG90YWwgZ2FzIGZsdXggYXQgdGhlIHBvcHVsYXRpb24gbGV2ZWwsIHdoaWNoIHJlcXVpcmVkIHNjYWxpbmcgdXAgZnJvbSBsYWtlLWxldmVsIGVzdGltYXRlcy4gVGhlIHR5cGljYWwgTVJQIHByb2Nlc3MgaXMgY2FycmllZCBvdXQgaW4gdHdvIHN0ZXBzLiBUaGUgZmlyc3Qgc3RlcCBpcyB0byBmaXQgcmVncmVzc2lvbiBtb2RlbHMgZm9yIHRoZSByZXNwb25zZSB2YXJpYWJsZXMgb2YgaW50ZXJlc3QgKGUuZy4sIGRpc3NvbHZlZCBOMk8sIGVxdWlsaWJyaXVtIE4yTykgY29uZGl0aW9uYWwgb24gdGhlIHN1cnZleSBkZXNpZ24gdmFyaWFibGVzIOKUvChpLmUuLCBlY29yZWdpb24sIHN0YXRlLCBsYWtlIHNpemUpLiBUaGUgc2Vjb25kIHN0ZXAgaXMgcG9zdC1zdHJhdGZpY2F0aW9uLCB3aGVyZWluIHRoZSBwb3N0ZXJpb3IgcGFyYW1ldGVyIGVzdGltYXRlcyBmcm9tIHRoZSByZWdyZXNzaW9uIG1vZGVsIGZvciB0aGUgc2FtcGxlIHBvcHVsYXRpb24gYXJlIHdlaWdodGVkIGJhc2VkIG9uIHRoZWlyIGtub3duIG9yIGFzc3VtZWQgZGlzdHJpYnV0aW9uIGluIHRoZSBwb3B1bGF0aW9uIG9mIGludGVyZXN0IFtpLmUuLCBwb3N0LXN0cmF0aWZpY2F0aW9uIHRhYmxlOyBAR2VsbWFuX2V0YWxfMjAyMCBDaC4gMTddLiBUaGUgcG9zdHN0cmF0aWZpY2F0aW9uIHRhYmxlIGluIG91ciBjYXNlLCBmb3IgZXhhbXBsZSwgd291bGQgYmUgYSBwb3B1bGF0aW9uIHN1bW1hcnkgb2YgbGFrZXMgYW1vbmcgdGhlIGRlc2lnbiB2YXJpYWJsZXM6IGVjb3JlZ2lvbiwgc3RhdGUsIGFuZCBzaXplIGNhdGVnb3J5LiBIb3dldmVyLCBiZWNhdXNlIHdlIGV2ZW50dWFsbHkgbmVlZGVkIGxha2UtbGV2ZWwgZXN0bWF0ZXMsIGluc3RlYWQgb2YgcHJlZGljdGluZyB0byBhIHBvc3RyYXRpZmljYXRpb24gdGFibGUsIHdlIHByZWRpY3RlZCB0byBlYWNoIGluZGl2aWR1YWwgbGFrZSBpbiB0aGUgcG9wdWxhdGlvbiBvZiBpbnRlcmVzdC4gVGhpcyBtZWFudCBwcmVkaWN0aW5nIHRvIHRoZSBmdWxsIHRhcmdldCBwb3B1bGF0aW9uIG9mIDQ2NSw4OTcgbmF0dXJhbCBhbmQgbWFuIG1hZGUgVVMgbGFrZXMgbGFyZ2VyIHRoYW4gNCBoZWN0YXJlcyBpbiB0aGUgbG93ZXIgNDggc3RhdGVzLiBUaGVzZSBwcmVkaWN0aW9ucyB3ZXJlIGFzc3VtZWQgcmVsZXZhbnQgdG8gYXZlcmFnZSBjb25kaXRpb25zIGR1cmluZyB0aGUgImluZGV4IHBlcmlvZCIgZm9yIGVhY2ggbGFrZSBpbiAyMDE3LiBEZXRhaWxzIGFib3V0IHRoZSBzYW1wbGluZyBmcmFtZSBhcyB3ZWxsIGFzIHRoZSB0YXJnZXQgcG9wdWxhdGlvbiBhcmUgZnVydGhlciBjbGFyaWZpZWQgaW4gdGhlIHdvcmtib29rIGJlbG93IHdpdGggZGF0YSBzdW1tYXJpZXMgYW5kIGNvZGUuIA0KDQpGb3IgdGhlIHJlZ3Jlc3Npb25zLCB3ZSB1c2VkIG11bHRpbGV2ZWwgbW9kZWxzIGZpdCBpbiBhIGZ1bGx5IEJheWVzaWFuIGZhc2hpb24gTXVsdGlsZXZlbCBtb2RlbHMgYXJlIHRob3VnaHQgdG8gd29yayB3ZWxsIGluIHRoaXMgY29udGV4dCBiZWNhdXNlIHRoZXkgcHJvdmlkZSByZWd1bGFyaXplZCBlc3RpbWF0ZXMgYWxvbmcgdGhlIGRlc2lnbiBncm91cGluZ3MsIHdoaWNoIGNhbiBpbXByb3ZlIG91dC1vZi1zYW1wbGUgaW5mZXJlbmNlcyBbQE1jRWxyZWF0aF8yMDIwXS4gSW5mZXJlbmNlcyBmb3IgbGFrZSB0eXBlcyB0aGF0IG1heSBiZSBtaXNzaW5nIGZyb20gdGhlIHNhbXBsZSwgYnV0IGFyZSBwYXJ0IG9mIHRoZSBwb3B1bGF0aW9uIG9mIGludGVyZXN0IGFyZSBhbHNvIHN0cmFpZ2h0Zm9yd2FyZCB1c2luZyB0aGlzIGFwcHJvYWNoIFtAR2VsbWFuX2V0YWxfMjAyMCBDaC4gMTc7IEBNY0VscmVhdGhfMjAyMF0uIE1vcmUgaW5mb3JtYXRpb24gdGhlc2UgbW9kZWxzLCB0aGVpciBzcGVjaWZpYyBwYXJhbWV0ZXJzLCBSIGNvZGUsIGZpdCBldmFsdWF0aW9ucywgYW5kIHJlc3VsdGluZyBpbmZlcmVuY2VzIGFyZSBwcmVzZW50ZWQgaW4gdGhpcyBkb2N1bWVudC4NCg0KVGhlIG92ZXJyaWRpbmcgb2JqZWN0aXZlIG9mIHRoZSBtb2RlbGluZyBlZmZvcnQgd2FzIHRvIHByb3ZpZGUgcG9wdWxhdGlvbiBsZXZlbCBlc3RpbWF0ZXMgZm9yICgxKSBkaXNzb2x2ZWQgYW5kIGVxdWlsaWJyaXVtIE4yTyBjb25jZW50cmF0aW9uczsgKDIpIHRoZSBOMk8gc2F0dXJhdGlvbiByYXRpbyAoaS5lLiwgZGlzc29sdmVkIE4yTy9lcXVpbGlicml1bSBOMk8pOyBhbmQgKDMpIHRoZSBwcm9wb3J0aW9uIG9mIHVuZGVyLXNhdHVyYXRlZCB3YXRlciBib2RpZXMgKGkuZS4sIHNhdHVyYXRpb24gcmF0aW8gPCAxKS4gVGhlIGVzdGltYXRlcyB3b3VsZCBhbHNvIGJlIHVzZWQgdG8gbGF0ZXIgZXN0aW1hdGUgdGhlIHRvdGFsIGZsdXggb2YgTjJPIGdhcyBhdHRyaWJ1dGFibGUgdG8gdGhlIHRhcmdldCBwb3B1bGF0aW9uIG9mIGxha2VzIG92ZXIgdGhlIGluZGV4IHBlcmlvZC4gVGhlIHNhdHVyYXRpb24gcmF0aW8gZXN0aW1hdGVzIHdlcmUgY2FsY3VsYXRlZCBhcyBhIGRlcml2ZWQgcXVhbnRpdHkgYmFzZWQgb24gdGhlIHJhdGlvIG9mIG1vZGVsZWQgZGlzc29sdmVkIHRvIGVxdWlsaWJyaXVtIE4yTy4gQmVjYXVzZSBkaXNzb2x2ZWQgYW5kIGVxdWlsaWJyaXVtIE4yTyB3ZXJlIG9ic2VydmVkIG9uIHRoZSBzYW1lIHNhbXBsZSB1bml0cyAobGFrZSBzaXRlcyksIHdlIGRldmVsb3BlZCBtb2RlbHMgZm9yIGVzdGltYXRpbmcgdGhlaXIgam9pbnQgZGlzdHJpYnV0aW9uLiBUaGUgcmVzcG9uc2UgdmFyaWFibGUgaW4gdGhlIG1vZGVscyB3YXMsIHRoZXJlZm9yZSwgbXVsdGl2YXJpYXRlIHRvIGFjY291bnQgZm9yIHBvdGVudGlhbCBzdGF0aXN0aWNhbCBkZXBlbmRlbmNpZXMgYmV0d2VlbiBkaXNzb2x2ZWQgYW5kIGVxdWlsaWJyaXVtIE4yTyBkdWUgdG8sIGZvciBleGFtcGxlLCBjb21tb24gZGVwZW5kZW5jaWVzIG9uIGdlb2dyYXBoeS4gQWx0aG91Z2ggcG9pbnQgcHJlZGljdGlvbnMgb2YgdGhlIG1lYW4gbWFyZ2luYWwgcHJvYmFiaWxpdGllcyBmcm9tIHNlcGFyYXRlIG1vZGVscyBjb3VsZCBiZSBjb21wYXJhYmxlLCBhIGpvaW50IG1vZGVsIGFsbG93aW5nIGNvcnJlbGF0ZWQgb2JzZXJ2YXRpb24tbGV2ZWwgZXJyb3JzIChpLmUuLCByZXNpZHVhbHMpIHdhcyBleHBlY3RlZCB0byBiZXR0ZXIgY2FwdHVyZSB1bmNlcnRhaW50eSBhbmQgcG90ZW50aWFsbHkgaW1wcm92ZSBvdXQtb2Ytc2FtcGxlIHByZWRpY3Rpb25zLCBzaG91bGQgdGhlIHZhcmlhYmxlcyBiZSBjb25kaXRpb25hbGx5IGNvcnJlbGF0ZWQgW0BXYXJ0b25fZXRhbF8yMDE1OyBAUG9nZ2lhdG9fZXRhbF8yMDIxXS4gQWxsIG9mIHRoZSBtb2RlbHMgZml0IHdlcmUgY29uc3RydWN0ZWQgdXNpbmcgdGhlIGBicm1zYCBwYWNrYWdlIFtAQnVya25lcl8yMDE3XSBpbiBgUmAgW0BSX0NvcmVfVGVhbV8yMDIxXSBhcyBhbiBpbnRlcmZhY2UgdG8gU3RhbiwgYSBzb2Z0d2FyZSBwYWNrYWdlIGZvciBmaXR0aW5nIGZ1bGx5IEJheWVzaWFuIG1vZGVscyB2aWEgSGFtaWx0b25pYW4gTW9udGUgQ2FybG8gW0hNQzsgQFN0YW5fRGV2ZWxvcG1lbnRfVGVhbV8yMDE4X2E7IEBTdGFuX0RldmVsb3BtZW50X1RlYW1fMjAxOF9iOyBAU3Rhbl9EZXZlbG9wbWVudF9UZWFtXzIwMThfY10uDQoNCiMgRGF0YQ0KQXMgZXhwbGFpbmVkIGluIGEgcHJldmlvdXMgZGF0YSBtdW5naW5nIGRvY3VtZW50IGRvY3VtZW50DQooaHR0cHM6Ly9naXRodWIuY29tL1VTRVBBL0Rpc3NvbHZlZEdhc05sYS9ibG9iL21hc3Rlci9zY3JpcHRzL2RnSW5kaWNhdG9yQW5hbHlzaXMuaHRtbCksIGR1cGxpY2F0ZSBkaXNzb2x2ZWQgZ2FzIHNhbXBsZXMgd2VyZSBjb2xsZWN0ZWQgYXQgYSBkZXB0aCBvZiB+MC4xbSBhdCBkZXNpZ25hdGVkIGluZGV4IHNpdGVzIGRpc3RyaWJ1dGVkIGFjcm9zcyAxMDkxIGxha2VzIG5hdGlvbndpZGUsIG9mIHdoaWNoIDk1IHdlcmUgc2FtcGxlZCB0d2ljZSBhcyByZXBlYXQgdmlzaXRzLiBUaGlzIHJhbmRvbWx5IHNlbGVjdGVkIHN1YnNldCBvZiByZXZpc2l0IHNpdGVzIHdhcyB1c2VkIGFzIGEgdGVzdCBzZXQgZm9yIGFzc2Vzc2luZyBtb2RlbCBmaXQgYW5kIG91dC1vZi1zYW1wbGUgcGVyZm9ybWFuY2UuIA0KDQpHYXMgc2FtcGxlcyB3ZXJlIGFuYWx5emVkIHZpYSBnYXMgY2hyb21vdG9ncmFwaHkgYW5kIGNvbmNlbnRyYXRpb25zIHdlcmUgcmVjb3JkZWQgdG8gdGhlIG5lYXJlc3QgMC4wMDEgbm1vbC9MLiBUaGUgc2FtcGxlcyB3ZXJlIGNvbGxlY3RlZCB1bmRlciBhIHN0cmF0aWZpZWQsIHVuZXF1YWwgcHJvYmFiaWxpdHkgZGVzaWduIGFuZCBlYWNoIGdhcyBvYnNlcnZhdGlvbiB3YXMgaW5kZXhlZCB0byBhbiBpbmRpdmlkdWFsIGxha2Ugc2VsZWN0ZWQgd2l0aCB1bmVxdWFsIHByb2JhYmlsaXR5IGZyb20gNSBkaWZmZXJlbnQgbGFrZSBzaXplIGNhdGVnb3JpZXMsICRqIFxpbiBqPTEsLi4uLEogPSA1JCwgYWNjb3JkaW5nIHRvIHN1cmZhY2UgYXJlYSAoaGEpLCBhbmQgZnJvbSB3aXRoaW4gYSBzdGF0ZSwgJGsgXGluIGs9MSwuLi4sSyA9IDQ4JCwgc2l0dWF0ZWQgd2l0aGluIGFuIGFnZ3JlZ2F0ZWQsIFdTQTkgb3IgT21lcm5payBlY29yZWdpb24sICRsIFxpbiBsPTEsLi4uLEwgPSA5JC4gQWxsIDkgV1NBOSBlY29yZWdpb25zIHdlcmUgcmVwcmVzZW50ZWQgaW4gdGhlIHNhbXBsZSwgaW5jbHVkaW5nIFhlcmljIChYRVIpLCBXZXN0ZXJuIE1vdW50YWluIChXTVQpLCAgTm9ydGhlcm4gUGxhaW5zIChOUEwpLCBTb3V0aGVybiBQbGFpbnMgKFNQTCksIFRlbXBlcmF0ZSBQbGFpbnMgKFRQTCksIENvYXN0YWwgUGxhaW5zIChDUEwpLCBVcHBlciBNaWR3ZXN0IChVTVcpLCBOb3J0aGVybiBBcHBhbGFjaGlhbiAoTkFQKSwgYW5kIFNvdXRoZXJuIEFwcGFsYWNoaWFuIChTQVApIHJlZ2lvbnMuIEFzIHNob3duIGJlbG93LCB0aGUgZGF0YSBmcm9tIHRoZSBpbml0aWFsIGFuZCByZXZpc2l0IHNhbXBsZXMgd2VyZSBzZXBhcmF0ZWx5IGNvbXBpbGVkIGludG8gZGF0YSBmcmFtZSBvYmplY3RzIGluICRcdGV4dGJme1J9JCwgd2l0aCAkbj05ODQkIGFuZCAkbj05NSQgcm93cywgcmVzcGVjdGl2ZWx5LCBvZiBnYXMgb2JzZXJ2YXRpb25zIGluZGV4ZWQgdG8gdGhlIHN1cnZleSBkZXNpZ24gdmFyaWFibGVzIGFuZCBzZXZlcmFsIHBvdGVudGlhbGx5IHJlbGV2YW50IGNvdmFyaWF0ZXMuIA0KDQojIyBJbXBvcnQNClRoZSBnYXMgZGF0YSBhbmQgY292YXJpYXRlcyB3ZXJlIHByZXZpb3VzbHkgZGVzY3JpYmVkIGFuZCBtdW5nZWQgYXQgDQpodHRwczovL2dpdGh1Yi5jb20vVVNFUEEvRGlzc29sdmVkR2FzTmxhL2Jsb2IvbWFzdGVyL3NjcmlwdHMvZGF0YU11bmdlLmh0bWwuIFRoYXQgZGF0YXNldCB3YXMgaW1wb3J0ZWQgYmVsb3cuIA0KYGBge3IgaW1wb3J0X2RhdGEsIGV2YWw9RkFMU0UsIGluY2x1ZGU9VFJVRX0NCmxvYWQoIGZpbGUgPSBwYXN0ZTAoIGxvY2FsUGF0aCwNCiAgICAgICAgICAgICAgIi9FbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpLyIsDQogICAgICAgICAgICAgICJPUkQgTkxBMTcgRGlzc29sdmVkIEdhcyAtIERvY3VtZW50cy8iLA0KICAgICAgICAgICAgICAiaW5wdXREYXRhL2RnLjIwMjEtMDItMDEuUkRhdGEiKQ0KICAgICAgKQ0KDQpzYXZlKGRnLCBmaWxlID0gIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2RnLnJkYSIpIA0KYGBgDQoNCkZyb20gdGhlIGltcG9ydGVkIGRhdGFzZXQsIGEgbmV3IGRhdGEgZnJhbWUgZm9yIG1vZGVsaW5nIHdhcyBjb25zdHJ1Y3RlZCBmcm9tIHRoZSBvcmlnaW5hbCBmaWxlIGluY2x1ZGluZyBvbmx5IHRoZSB2YXJpYWJsZXMgb2YgaW50ZXJlc3Q6ICgxKSB0aGUgTjJPIGdhcyBvYnNlcnZhdGlvbnM7ICgyKSB0aGUgc3VydmV5IGRlc2lnbiB2YXJpYWJsZXMgaW5kZXhlZCB0byB0aG9zZSBvYnNlcnZhdGlvbnM7IGFuZCAoMykgYWRkaXRpb25hbCBjb3ZhcmlhdGVzIGNvbnNpZGVyZWQgcG90ZW50aWFsbHkgdXNlZnVsIGZvciBpbXByb3ZpbmcgdGhlIGZpdCBvZiB0aGUgbW9kZWwuIFRoZSBkYXRhIGZyYW1lIGJlbG93IGV4Y2x1ZGVkIHRoZSBzZWNvbmQtdmlzaXQgb2JzZXJ2YXRpb25zLCB3aGljaCB3b3VsZCBsYXRlciBiZSB1c2VkIGZvciBtb2RlbCBjaGVja2luZy4gU29tZSB2YXJpYWJsZXMgZnJvbSB0aGUgaW1wb3J0ZWQgZGF0YSB3ZXJlIHJlbmFtZWQgZm9yIGNvbnZlbmllbmNlLiBJbiBhZGRpdGlvbiwgdGhlIE5PMyBjb3ZhcmlhdGUgd2FzIHJvdW5kZWQgYWNjb3JkaW5nIHRvIHRoZSBkb2N1bWVudGVkIG1lYXN1cmVtZW50IHByZWNpc2lvbi4gQW4gYWx0ZXJuYXRpdmUgdmVyc2lvbiBvZiB0aGUgTk8zIGNvdmFyaWF0ZSB3YXMgYWxzbyBjcmVhdGVkIGluIHRoaXMgc3RlcCBieSBsb2ctdHJhbnNmb3JtaW5nIGFuZCByZS1jb2RpbmcgaXQgYXMgYW4gb3JkZXJlZCBmYWN0b3Igd2l0aCBmaXZlIGxldmVscyBhdCBoYW5kLWRyYXduIGN1dCBwb2ludHMuIFRoZSBsZWZ0LW1vc3QgY3V0IHBvaW50IHNlcGFyYXRlZCBvYnNlcnZhdGlvbnMgYmVsb3cgdGhlIGRldGVjdGlvbiBsaW1pdCBmcm9tIHRoZSBjb21wbGV0ZWx5IG9ic2VydmVkIHNhbXBsZXMuIFRoZSByZW1haW5pbmcgY3V0IHBvaW50cyBpbiB0aGUgcG9zaXRpdmUgZGlyZWN0aW9uIHdlcmUgZHJhd24gYXQgYXBwcm94aW1hdGVseSBlcXVhbCBkaXN0YW5jZXMgYWxvbmcgdGhlIGxvZyBzY2FsZS4gRmluYWxseSwgaXQgc2hvdWxkIGJlIG5vdGVkIHRoYXQgb25lIGxha2UgdGhhdCB3YXMgc2FtcGxlZCB3YXMgbWlzc2luZyBpbmZvcm1hdGlvbiBvbiB0aGUgTjJPIGdhcyBtZWFzdXJlbWVudHMgYW5kIGl0IHdhcyByZW1vdmVkIGZyb20gdGhlIGRhdGEgZnJhbWUuDQpgYGB7ciBtb2RlbF9kYXRhLCBlY2hvPVRSVUUsIHBhZ2VkLnByaW50PVRSVUV9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZy5yZGEiKQ0KDQpkZyAlPiUNCiAgZmlsdGVyKCFpcy5uYShkaXNzb2x2ZWQubjJvLm5tb2wpKSAlPiUgIyAxIG9icyB3aXRoIG1pc3NpbmcgbWVhc3VyZW1lbnQNCiAgbnJvdygpICMgbnVtYmVyIG9mIG9ic2VydmF0aW9ucyBiZWZvcmUgZmlsdGVyaW5nDQoNCmRmX21vZGVsIDwtIGRnICU+JQ0KICBmaWx0ZXIoIWlzLm5hKGRpc3NvbHZlZC5uMm8ubm1vbCkpICU+JQ0KICBmaWx0ZXIoc2l0ZXR5cGUgPT0gIlBST0IiKSAlPiUgIyBwcm9iYWJpbGl0eSBzYW1wbGVzIG9ubHkNCiAgZmlsdGVyKHZpc2l0Lm5vID09IDEpICU+JQ0KICBtdXRhdGUobjJvID0gcm91bmQoZGlzc29sdmVkLm4yby5ubW9sLCAyKSwNCiAgICAgICAgIG4yb19lcSA9IHJvdW5kKHNhdC5uMm8ubm1vbCwgMiksDQogICAgICAgICBuMm9fc2F0ID0gbjJvLnNhdC5yYXRpbywNCiAgICAgICAgIG4yb19lbSA9IGUubjJvLm5tb2wuZCwNCiAgICAgICAgIG4yb19mbHV4ID0gZi5uMm8ubS5kLA0KICAgICAgICAgV1NBOSA9IGZhY3RvcihhZy5lY285KSwNCiAgICAgICAgIHN0YXRlID0gZmFjdG9yKHN0YXRlLmFiYlttYXRjaChzdGF0ZS5ubSwgc3RhdGUubmFtZSldKSwNCiAgICAgICAgIGFyZWFfaGEgPSBhcmVhLmhhLA0KICAgICAgICAgbG9nX2FyZWEgPSBsb2coYXJlYV9oYSksDQogICAgICAgICBjaGxhID0gY2hsYS5yZXN1bHQsDQogICAgICAgICBsb2dfY2hsYSA9IGxvZyhjaGxhKSwNCiAgICAgICAgIGVsZXYgPSBlbGV2YXRpb24sDQogICAgICAgICBsb2dfZWxldiA9IGxvZyhlbGV2ICsgMSksDQogICAgICAgICBkb19zdXJmID0gbzIuc3VyZiwNCiAgICAgICAgIGxvZ19kbyA9IGxvZyhkb19zdXJmKSwNCiAgICAgICAgIGJmX21heCA9IG1heC5iZiwNCiAgICAgICAgIHNxcnRfYmYgPSBzcXJ0KGJmX21heCksDQogICAgICAgICBzaXplX2NhdCA9IHJlY29kZShhcmVhLmNhdDYsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIigxLDRdIiA9ICJtaW5fNCIgLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIigxMCwyMF0iID0gIjEwXzIwIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICIoMjAsNTBdIiA9ICIyMF81MCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAiKDQsMTBdIiA9ICI0XzEwIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICI+NTAiID0gIjUwX21heCIpKSAlPiUNCiAgbXV0YXRlKHNpemVfY2F0ID0gZmFjdG9yKHNpemVfY2F0LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygibWluXzQiLCAiNF8xMCIsICIxMF8yMCIsICIyMF81MCIsICI1MF9tYXgiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgPSBUUlVFKSkgJT4lDQogIG11dGF0ZShubzMgPSBpZmVsc2Uobml0cmF0ZS5uLnJlc3VsdCA8PSAwLjAwMDUsIDAuMDAwNSwgcm91bmQobml0cmF0ZS5uLnJlc3VsdCwgNCkpKSAlPiUjIDEvMiBtZGwgMC4wMQ0KICBtdXRhdGUobm8zX2NhdCA9IGN1dChsb2cobm8zKSwgIyBjb252ZXJ0IG5vMyB0byBvcmRlcmVkIGZhY3RvciB3aXRoIDUgbGV2ZWxzDQogICAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoLUluZiwgLTcuNSwgLTUuNSwgLTMuNSwgLTEuNSwgSW5mKSwNCiAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID1zZXEoMSwgNSwgMSkpKSAlPiUNCiAgbXV0YXRlKG5vM19jYXQgPSBmYWN0b3Iobm8zX2NhdCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gc2VxKDEsIDUsIDEpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBvcmRlcmVkID0gVFJVRSkpICU+JQ0KICBtdXRhdGUoZGF0ZSA9IGFzLkRhdGUoZGF0ZS5jb2wpKSAlPiUNCiAgbXV0YXRlKGpkYXRlID0gYXMubnVtZXJpYyhmb3JtYXQoZGF0ZSwgIiVqIikpKSAlPiUgDQogIG11dGF0ZShsYXQgPSBtYXAubGF0LmRkLA0KICAgICAgICAgbG9uID0gbWFwLmxvbi5kZCkgJT4lICMgbG9uZ2l0dWRlDQogIG11dGF0ZShzdXJmdGVtcCA9IHN1cmZ0ZW1wLA0KICAgICAgICAgbG9nX3N1cmZ0ZW1wID0gbG9nKHN1cmZ0ZW1wKSkgJT4lIA0KICBzZWxlY3QoV1NBOSwNCiAgICAgICAgIHN0YXRlLA0KICAgICAgICAgc2l6ZV9jYXQsDQogICAgICAgICBzaXRlLmlkLA0KICAgICAgICAgbGF0LA0KICAgICAgICAgbG9uLA0KICAgICAgICAgZGF0ZSwNCiAgICAgICAgIGpkYXRlLA0KICAgICAgICAgc3VyZnRlbXAsDQogICAgICAgICBsb2dfc3VyZnRlbXAsDQogICAgICAgICBhcmVhX2hhLA0KICAgICAgICAgbG9nX2FyZWEsDQogICAgICAgICBlbGV2LA0KICAgICAgICAgbG9nX2VsZXYsDQogICAgICAgICBjaGxhLA0KICAgICAgICAgbG9nX2NobGEsDQogICAgICAgICBkb19zdXJmLA0KICAgICAgICAgbG9nX2RvLA0KICAgICAgICAgYmZfbWF4LA0KICAgICAgICAgc3FydF9iZiwNCiAgICAgICAgIG4ybywNCiAgICAgICAgIG4yb19lcSwNCiAgICAgICAgIG5vMywNCiAgICAgICAgIG5vM19jYXQNCiAgICAgICAgICkNCg0Kc2F2ZShkZl9tb2RlbCwgZmlsZSA9ICJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZl9tb2RlbC5yZGEiKSANCg0KbnJvdyhkZl9tb2RlbCkgIyBudW1iZXIgb2Ygb2JzIGFmdGVyIGZpbHRlcmluZw0KDQpwcmludChkZl9tb2RlbCkNCmBgYA0KDQpBIHNlY29uZCBkYXRhZnJhbWUsIGluY2x1ZGluZyBvbmx5IHRoZSBzZWNvbmQgdmlzaXQgb2JzZXJ2YXRpb25zLCB3YXMgY29uc3RydWN0ZWQgYmVsb3cuIFRoZXNlIGRhdGEgd2VyZSBsYXRlciB1c2VkIGFzIGEgInRlc3Qgc2V0IiB0byBhc3Nlc3MgdGhlIG91dC1vZi1zYW1wbGUgZml0IG9mIHRoZSBtb2RlbCBkZXZlbG9wZWQgb24gdGhlIGZpcnN0LXZpc2l0IG9yIHRyYWluaW5nIGRhdGEuDQpgYGB7ciB0ZXN0X2RhdGEsIGVjaG89VFJVRSwgcGFnZWQucHJpbnQ9VFJVRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2RnLnJkYSIpDQoNCiMgbnVtYmVyIG9mIG9ic2VydmF0aW9ucyBiZWZvcmUgZmlsdGVyaW5nIHByb2JhYmlsaXR5IHNhbXBsZXMNCmRnICU+JQ0KICBmaWx0ZXIoIWlzLm5hKGRpc3NvbHZlZC5uMm8ubm1vbCkpICU+JSAjIHJlbW92ZSBvYnMgd2l0aCBtaXNzaW5nIHJlc3BvbnNlIG1lYXN1cmVtZW50cw0KICBucm93KCkNCg0KZGZfdGVzdCA8LSBkZyAlPiUNCiAgZmlsdGVyKCFpcy5uYShkaXNzb2x2ZWQubjJvLm5tb2wpKSAlPiUNCiAgZmlsdGVyKHNpdGV0eXBlID09ICJQUk9CIikgJT4lICMgcHJvYmFiaWxpdHkgc2FtcGxlcyBvbmx5DQogIGZpbHRlcih2aXNpdC5ubyA9PSAyKSAlPiUNCiAgbXV0YXRlKG4ybyA9IHJvdW5kKGRpc3NvbHZlZC5uMm8ubm1vbCwgMiksDQogICAgICAgICBuMm9fZXEgPSByb3VuZChzYXQubjJvLm5tb2wsIDIpLA0KICAgICAgICAgbjJvX3NhdCA9IG4yby5zYXQucmF0aW8sDQogICAgICAgICBuMm9fZW0gPSBlLm4yby5ubW9sLmQsDQogICAgICAgICBuMm9fZmx1eCA9IGYubjJvLm0uZCwNCiAgICAgICAgIFdTQTkgPSBmYWN0b3IoYWcuZWNvOSksDQogICAgICAgICBzdGF0ZSA9IGZhY3RvcihzdGF0ZS5hYmJbbWF0Y2goc3RhdGUubm0sIHN0YXRlLm5hbWUpXSksDQogICAgICAgICBhcmVhX2hhID0gYXJlYS5oYSwNCiAgICAgICAgIGxvZ19hcmVhID0gbG9nKGFyZWFfaGEpLA0KICAgICAgICAgY2hsYSA9IGNobGEucmVzdWx0LA0KICAgICAgICAgbG9nX2NobGEgPSBsb2coY2hsYSksDQogICAgICAgICBlbGV2ID0gZWxldmF0aW9uLA0KICAgICAgICAgbG9nX2VsZXYgPSBsb2coZWxldiArIDEpLA0KICAgICAgICAgZG9fc3VyZiA9IG8yLnN1cmYsDQogICAgICAgICBsb2dfZG8gPSBsb2coZG9fc3VyZiksDQogICAgICAgICBiZl9tYXggPSBtYXguYmYsDQogICAgICAgICBzcXJ0X2JmID0gc3FydChiZl9tYXgpLA0KICAgICAgICAgc2l6ZV9jYXQgPSByZWNvZGUoYXJlYS5jYXQ2LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICIoMSw0XSIgPSAibWluXzQiICwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICIoMTAsMjBdIiA9ICIxMF8yMCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAiKDIwLDUwXSIgPSAiMjBfNTAiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIig0LDEwXSIgPSAiNF8xMCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAiPjUwIiA9ICI1MF9tYXgiKSkgJT4lDQogIG11dGF0ZShzaXplX2NhdCA9IGZhY3RvcihzaXplX2NhdCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIm1pbl80IiwgIjRfMTAiLCAiMTBfMjAiLCAiMjBfNTAiLCAiNTBfbWF4IiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICBvcmRlcmVkID0gVFJVRSkpICU+JQ0KICBtdXRhdGUobm8zID0gaWZlbHNlKG5pdHJhdGUubi5yZXN1bHQgPD0gMC4wMDA1LCAwLjAwMDUsIHJvdW5kKG5pdHJhdGUubi5yZXN1bHQsIDQpKSkgJT4lIyAxLzIgbWRsIDAuMDENCiAgbXV0YXRlKG5vM19jYXQgPSBjdXQobG9nKG5vMyksICMgY29udmVydCBubzMgdG8gb3JkZXJlZCBmYWN0b3Igd2l0aCA1IGxldmVscw0KICAgICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKC1JbmYsIC03LjUsIC01LjUsIC0zLjUsIC0xLjUsIEluZiksDQogICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9c2VxKDEsIDUsIDEpKSkgJT4lDQogIG11dGF0ZShubzNfY2F0ID0gZmFjdG9yKG5vM19jYXQsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IHNlcSgxLCA1LCAxKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpKSAlPiUNCiAgbXV0YXRlKGRhdGUgPSBhcy5EYXRlKGRhdGUuY29sKSkgJT4lDQogIG11dGF0ZShqZGF0ZSA9IGFzLm51bWVyaWMoZm9ybWF0KGRhdGUsICIlaiIpKSkgJT4lIA0KICBtdXRhdGUobGF0ID0gbWFwLmxhdC5kZCwNCiAgICAgICAgIGxvbiA9IG1hcC5sb24uZGQpICU+JSAjIGxvbmdpdHVkZQ0KICBtdXRhdGUoc3VyZnRlbXAgPSBzdXJmdGVtcCwNCiAgICAgICAgIGxvZ19zdXJmdGVtcCA9IGxvZyhzdXJmdGVtcCkpICU+JSANCiAgc2VsZWN0KFdTQTksDQogICAgICAgICBzdGF0ZSwNCiAgICAgICAgIHNpemVfY2F0LA0KICAgICAgICAgc2l0ZS5pZCwNCiAgICAgICAgIGxhdCwNCiAgICAgICAgIGxvbiwNCiAgICAgICAgIGRhdGUsDQogICAgICAgICBqZGF0ZSwNCiAgICAgICAgIHN1cmZ0ZW1wLA0KICAgICAgICAgbG9nX3N1cmZ0ZW1wLA0KICAgICAgICAgYXJlYV9oYSwNCiAgICAgICAgIGxvZ19hcmVhLA0KICAgICAgICAgZWxldiwNCiAgICAgICAgIGxvZ19lbGV2LA0KICAgICAgICAgY2hsYSwNCiAgICAgICAgIGxvZ19jaGxhLA0KICAgICAgICAgZG9fc3VyZiwNCiAgICAgICAgIGxvZ19kbywNCiAgICAgICAgIGJmX21heCwNCiAgICAgICAgIHNxcnRfYmYsDQogICAgICAgICBuMm8sDQogICAgICAgICBuMm9fZXEsDQogICAgICAgICBubzMsDQogICAgICAgICBubzNfY2F0DQogICAgICAgICApDQoNCnNhdmUoZGZfdGVzdCwgZmlsZSA9ICJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZl90ZXN0LnJkYSIpIA0KDQpucm93KGRmX3Rlc3QpICMgbnVtYmVyIG9mIG9icyBhZnRlciBmaWx0ZXJpbmcgZm9yIHByb2JhYmlsaXR5IHNhbXBsZXMsIGZpcnN0IHZpc2l0cywgYW5kIHJlbW92aW5nIG9uZSBzaXRlIG1pc3NpbmcgZWNvcmVnaW9uIChXU0E5KSBpbmZvLg0KDQpwcmludChkZl90ZXN0KQ0KYGBgDQoNCiMjIFRhcmdldCBwb3B1bGF0aW9uDQpCZWxvdy4gdGhlIE5MQSBzYW1wbGluZyBmcmFtZSB3YXMgaW1wb3J0ZWQgYW5kIHRoZW4gZmlsdGVyZWQgdG8gaW5jbHVkZSBvbmx5IHRoZSB0YXJnZXQgcG9wdWxhdGlvbiBvciBzYW1wbGluZyBmcmFtZSBmb3IgdGhpcyBwcm9qZWN0Lg0KYGBge3IgaW1wb3J0X3NhbXBsZV9mcmFtZSwgZWNobz1UUlVFfQ0KZGZfcG9wIDwtIHJlYWQuY3N2KGZpbGUgPSBwYXN0ZTAobG9jYWxQYXRoLA0KICAgICAgICAgICAgICAiL0Vudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvIiwNCiAgICAgICAgICAgICAgIk9SRCBOTEExNyBEaXNzb2x2ZWQgR2FzIC0gRG9jdW1lbnRzLyIsDQogICAgICAgICAgICAgICJpbnB1dERhdGEvTkxBX1NhbXBsZV9GcmFtZS5jc3YiKSwgaGVhZGVyID0gVCkNCg0Kc2ZyYW1lIDwtIGRmX3BvcCAlPiUNCiAgZmlsdGVyKG5sYTE3X3NmICE9ICJFeGNsdWRlMjAxNyIpICU+JQ0KICBmaWx0ZXIobmxhMTdfc2YgIT0gIkV4Y2x1ZGUyMDE3X0luY2x1ZGUyMDE3TkgiKSAlPiUNCiAgZmlsdGVyKHN0YXRlICE9ICJEQyIpICU+JQ0KICBmaWx0ZXIoc3RhdGUgIT0gIkhJIikgJT4lDQogIGRyb3BsZXZlbHMoKSAlPiUNCiAgbXV0YXRlKFdTQTkgPSBmYWN0b3IoYWdfZWNvOSksDQogICAgICAgICBXU0E5ID0gZm9yY2F0czo6ZmN0X2Ryb3AoV1NBOSksICMgcmVtb3ZlIE5BIGxldmVsDQogICAgICAgICBzdGF0ZSA9IGZhY3RvcihzdGF0ZSksDQogICAgICAgICBzaXplX2NhdCA9IGZhY3RvcihhcmVhX2NhdDYpLA0KICAgICAgICAgbGF0ID0gbGF0X2RkODMsDQogICAgICAgICBsb24gPSBsb25fZGQ4MywNCiAgICAgICAgIGxvZ19hcmVhID0gbG9nKGFyZWFfaGEpLA0KICAgICAgICAgZWxldiA9IGVsZXZhdGlvbiwNCiAgICAgICAgIGxvZ19lbGV2ID0gaWZlbHNlKGVsZXYgPD0gMCwgMCwgZWxldiksICMgYXNzdW1lZCBlbGV2IDwgMCB0byBiZSBlbGV2ID0gMA0KICAgICAgICAgbG9nX2VsZXYgPSBsb2cobG9nX2VsZXYgKyAxKQ0KICAgICAgICAgKSAlPiUgDQogIG11dGF0ZShzaXplX2NhdCA9IHJlY29kZShzaXplX2NhdCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAiKDEsNF0iID0gIm1pbl80IiAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAiKDEwLDIwXSIgPSAiMTBfMjAiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIigyMCw1MF0iID0gIjIwXzUwIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICIoNCwxMF0iID0gIjRfMTAiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIj41MCIgPSAiNTBfbWF4IikpICU+JQ0KICBtdXRhdGUoc2l6ZV9jYXQgPSBmYWN0b3Ioc2l6ZV9jYXQsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygibWluXzQiLCAiNF8xMCIsICIxMF8yMCIsICIyMF81MCIsICI1MF9tYXgiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgPSBUUlVFKSkgJT4lDQogIHNlbGVjdChXU0E5LCBzdGF0ZSwgc2l6ZV9jYXQsIGxhdCwgbG9uLCBhcmVhX2hhLCBsb2dfYXJlYSwgZWxldiwgbG9nX2VsZXYpDQoNCnJtKGRmX3BvcCkNCg0Kc2F2ZShzZnJhbWUsIGZpbGUgPSAiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvc2ZyYW1lLnJkYSIpIA0KDQpwcmludChzZnJhbWUpDQpgYGANCg0KVGhlIHJlc3VsdGluZyB0YXJnZXQgcG9wdWxhdGlvbiBhYm92ZSBpbmNsdWRlZCBhIHRvdGFsIG9mIDQ2NSw4OTcgd2F0ZXJib2RpZXMuDQoNCkNyb3NzIHRhYnVsYXRpb25zIGJlbG93IGRlc2NyaWJlIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIHRhcmdldCBwb3B1bGF0aW9uIHdpdGggcmVzcGVjdCB0byB0aGUgZGVzaWduIHZhcmlhYmxlcy4gVGhlIGNyb3NzLXRhYnVsYXRpb24gbWFrZXMgaXQgY2xlYXIgdGhhdCBlYWNoIGVjb3JlZ2lvbiBkb2VzIG5vdCBjb250YWluIGVhY2ggc3RhdGUuIFRoZXJlZm9yZSwgaW4gdGhlIHN0YXRpc3RpY2FsIHNlbnNlLCBzdGF0ZXMgd2VyZSBuZXN0ZWQgaW4gZWNvcmVnaW9ucy4NCmBgYHtyIGZyYW1lX2RpbWVuc2lvbnNfMSwgZWNobz1UUlVFLCBtZXNzYWdlPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvc2ZyYW1lLnJkYSIpDQoNCnNmcmFtZSAlPiUNCiAgZ3JvdXBfYnkoV1NBOSwgc3RhdGUpICU+JQ0KICBzdW1tYXJpc2UobiA9IG4oKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIHNwcmVhZChzdGF0ZSwgbikgJT4lDQogIHByaW50KCkNCmBgYA0KDQpMaWtld2lzZSwgbGFrZSBzaXplIGNhdGVnb3J5IHdhcyBuZXN0ZWQgaW4gc3RhdGUgKHdoaWNoIHdhcyBuZXN0ZWQgaW4gZWNvcmVnaW9uKS4gVGhhdCBpcywgbm90IGV2ZXJ5IGVjb3JlZ2lvbjpzdGF0ZSBpbiB0aGUgcG9wdWxhdGlvbiBvZiBpbnRlcmVzdCBjb250YWluZWQgZXZlcnkgc2l6ZSBjYXRlZ29yeSAoYmVsb3cpLg0KYGBge3IgZnJhbWVfZGltZW5zaW9uc180LCBlY2hvPVRSVUUsIG1lc3NhZ2U9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9zZnJhbWUucmRhIikNCg0Kc2ZyYW1lICU+JQ0KICBncm91cF9ieShXU0E5LCBzdGF0ZSwgc2l6ZV9jYXQpICU+JQ0KICBzdW1tYXJpc2UobiA9IG4oKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIHNwcmVhZChzaXplX2NhdCwgbikgJT4lDQogIHByaW50KCkNCmBgYA0KDQpCZWxvdywgdGhlIHNhbXBsaW5nIGZyYW1lIHdhcyBzZWxlY3RlZCBkb3duIHRvIGNyZWF0ZSBhIHBvc3Qtc3RyYXRpZmljYXRpb24gdGFibGUuIFNvbWUgb2YgdGhlIHZhcmlhYmxlcyB3ZXJlIHJlbmFtZWQgdG8gbWF0Y2ggdGhlIG5hbWluZyBjb252ZW50aW9ucyB1c2VkIGluIHRoZSBvYnNlcnZhdGlvbmFsIGRhdGEgYWJvdmUuIFRoZXJlIHdlcmUgNTM2IHR5cGVzIG9mIGxha2VzIGluIHRoZSBwb3B1bGF0aW9uIG9mIGludGVyZXN0IHdpdGggcmVzcGVjdCB0byB0aGUgc2FtcGxpbmcgZGVzaWduLiBUaGUgY291bnRzIG9mIHRob3NlIGxha2UgdHlwZXMgKG5fbGFrZXMpIGFuZCB0aGVpciBwcm9wb3J0aW9ucyByZWxhdGl2ZSB0byB0aGUgdG90YWwgcG9wdWxhdGlvbiBvZiBsYWtlcyBpbiB0aGUgc2FtcGxpbmcgZnJhbWUgKHByb3BfY2VsbCkgYXJlIGluZGljYXRlZCBiZWxvdy4NCmBgYHtyIGZpbHRlcl9mcmFtZSwgZWNobz1UUlVFLCBtZXNzYWdlPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvc2ZyYW1lLnJkYSIpDQoNCnBmcmFtZSA8LSBzZnJhbWUgJT4lDQogIG11dGF0ZShvYnMgPSAxKSAlPiUNCiAgZ3JvdXBfYnkoV1NBOSwgc3RhdGUsIHNpemVfY2F0KSAlPiUNCiAgc3VtbWFyaXNlKG5fbGFrZXMgPSBzdW0ob2JzKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlKHByb3BfY2VsbCA9IG5fbGFrZXMvc3VtKG5fbGFrZXMpKSAlPiUNCiAgbXV0YXRlKHR5cGUgPSAicG9wdWxhdGlvbiIpIA0KDQpzYXZlKHBmcmFtZSwgZmlsZSA9ICJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9wZnJhbWUucmRhIikNCg0KcHJpbnQocGZyYW1lKQ0KYGBgDQoNCiMjIFNhbXBsZSB2cy4gcG9wdWxhdGlvbg0KQmVsb3csIHRoZSBsYWtlIGRpc3RyaWJ1dGlvbnMgaW4gdGhlIHBvcHVsYXRpb24gb2YgaW50ZXJlc3Qgd2VyZSBjb21wYXJlZCB0byB0aGUgcHJvcG9ydGlvbnMgaW4gdGhlIG9ic2VydmVkIHNhbXBsZS4gVGhlcmUgd2VyZSAzNTIgbGFrZSB0eXBlcyBpbiB0aGUgc2FtcGxlIGNvbXBhcmVkIHRvIHRoZSA1MzYgaW4gdGhlIHBvcHVsYXRpb24gb2Ygb2YgaW50ZXJlc3QuIEluIHRvdGFsLCB0aGVyZSB3ZXJlIDk4NCBvYnNlcnZhdGlvbnMgZGlzdHJpYnV0ZWQgYWNyb3NzIHRoZXNlIDM1MiBsYWtlIHR5cGVzIGluIHRoZSBzYW1wbGU7IGFuZCB0aGUgbnVtYmVyIG9mIHNhbXBsZXMgd2FzIG5vdCBkaXN0cmlidXRlZCBldmVubHkgYWNyb3NzIHRoZSB0eXBlcy4gU29tZSBjZWxscyB3ZXJlIHJlcHJlc2VudGVkIGJ5IGFzIGZldyBhcyAxIGxha2UuIEluIHRvdGFsLCA1MzYtMzUyID0gMTg0IGxha2UgdHlwZXMgaW4gdGhlIHBvcHVsYXRpb24gb2YgaW50ZXJlc3Qgd2VyZSBub3QgcmVwcmVzZW50ZWQgaW4gdGhlIHNhbXBsZS4NCmBgYHtyIHNhbXBsZV9jZWxsX2NvdW50cywgZWNobz1UUlVFLCBtZXNzYWdlPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvZGZfbW9kZWwucmRhIikNCg0Kc2FtcF9wcm9wcyA8LSBkZl9tb2RlbCAlPiUNCiAgbXV0YXRlKG9icyA9IDEpICU+JQ0KICBncm91cF9ieShXU0E5LCBzdGF0ZSwgc2l6ZV9jYXQpICU+JQ0KICBzdW1tYXJpemUobl9sYWtlcyA9IHN1bShvYnMpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUocHJvcF9jZWxsID0gcm91bmQobl9sYWtlcyAvIHN1bShuX2xha2VzKSwgNykpICU+JQ0KICBtdXRhdGUodHlwZSA9ICJzYW1wbGUiKSANCg0Kc2F2ZShzYW1wX3Byb3BzLCBmaWxlID0gIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL3NhbXBfcHJvcHMucmRhIikNCg0KcHJpbnQoc2FtcF9wcm9wcykNCmBgYA0KDQpCZWxvdywgYSBncmFwaGljYWwgY29tcGFyaXNvbiB3YXMgY29uc3RydWN0ZWQgdG8gZGVwaWN0IHRoZSBkaXN0cmlidXRpb24gb2YgY2VsbHMgaW4gdGhlIHBvcHVsYXRpb24gb2YgaW50ZXJlc3QgX3ZlcnN1c18gdGhvc2UgaW4gdGhlIHNhbXBsZS4NCmBgYHtyIGNvbXBhcmVfc2FtcGxlX3BvcF9jZWxscywgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD0xMH0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL3BmcmFtZS5yZGEiKQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvc2FtcF9wcm9wcy5yZGEiKQ0KDQpwZnJhbWUgJT4lDQogIGJpbmRfcm93cyhzYW1wX3Byb3BzKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gaW50ZXJhY3Rpb24oV1NBOSwgc3RhdGUsIHNpemVfY2F0KSwgeSA9IHByb3BfY2VsbCwgZ3JvdXAgPSB0eXBlLCBsaW5ldHlwZSA9IHR5cGUpKSArDQogIGdlb21fcG9pbnQoc3RhdCA9ICJpZGVudGl0eSIsIGFlcyggc2hhcGUgPSB0eXBlLCBjb2xvciA9IHR5cGUpKSArDQogIGdlb21fbGluZSgpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSkgKw0KICB4bGFiKCJXU0E5OnN0YXRlOnNpemUiKSArDQogIHlsYWIoInByb3BvcnRpb24gaW4gY2VsbCIpDQpgYGANCg0KQW5vdGhlciBjb21wYXJpc29uIGJldHdlZW4gcG9wdWxhdGlvbiBhbmQgc2FtcGxlIHdhcyBjb25zdHJ1Y3RlZCBiZWxvdyBieSBlY29yZWdpb24uIFRoZSBzYW1wbGVzIHdlcmUgbm90IGJhbGFuY2VkIGFjcm9zcyBlY29yZWdpb25zLiBMYWtlcyBpbiB0aGUgQ29hc3RhbCBQbGFpbnMgKENQTCkgZWNvcmVnaW9uLCBmb3IgZXhhbXBsZSwgd2VyZSBjbGVhcmx5IHVuZGVyc2FtcGxlZCByZWxhdGl2ZSB0byB0aGVpciBwcm9wb3J0aW9uIG9mIHRoZSBwb3B1bGF0aW9uLg0KYGBge3IgZWNvX3Byb3BzX3BvcCwgZXZhbD1GQUxTRSwgaW5jbHVkZT1UUlVFLCBtZXNzYWdlPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvcGZyYW1lLnJkYSIpDQoNCnBmcmFtZV9lY28gPC0gcGZyYW1lICU+JQ0KICBncm91cF9ieShXU0E5KSAlPiUNCiAgc3VtbWFyaXNlKG5fbGFrZXMgPSBzdW0obl9sYWtlcykpICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZShwcm9wX2NlbGwgPSByb3VuZChuX2xha2VzL3N1bShuX2xha2VzKSwgNykpICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZSh0eXBlID0gJ3BvcHVsYXRpb24nKSANCg0Kc2F2ZShwZnJhbWVfZWNvLCBmaWxlID0gIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL3BmcmFtZV9lY28ucmRhIikNCmBgYA0KDQpgYGB7ciBlY29fcHJvcHNfc2FtcGxlLCBldmFsPUZBTFNFLCBpbmNsdWRlPVRSVUUsIG1lc3NhZ2U9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9zYW1wX3Byb3BzLnJkYSIpDQoNCnNhbXBfcHJvcHNfZWNvIDwtIHNhbXBfcHJvcHMgJT4lDQogIGdyb3VwX2J5KFdTQTkpICU+JQ0KICBzdW1tYXJpc2Uobl9sYWtlcyA9IHN1bShuX2xha2VzKSkgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlKHByb3BfY2VsbCA9IHJvdW5kKG5fbGFrZXMvc3VtKG5fbGFrZXMpLCA3KSkgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlKHR5cGUgPSAnc2FtcGxlJykNCg0Kc2F2ZShzYW1wX3Byb3BzX2VjbywgZmlsZSA9ICJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9zYW1wX3Byb3BzX2Vjby5yZGEiKQ0KYGBgDQoNCmBgYHtyIGNvbXBhcmVfZWNvX3NhbXBsZV9wb3BfY2VsbHMsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9Nn0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL3BmcmFtZV9lY28ucmRhIikNCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL3NhbXBfcHJvcHNfZWNvLnJkYSIpDQoNCnBmcmFtZV9lY28gJT4lDQogIGJpbmRfcm93cyhzYW1wX3Byb3BzX2VjbykgJT4lDQogIGdncGxvdChtYXBwaW5nID0gYWVzKHggPSBXU0E5LCB5ID0gcHJvcF9jZWxsLCBncm91cCA9IHR5cGUsIGxpbmV0eXBlID0gdHlwZSkpICsNCiAgZ2VvbV9wb2ludChzdGF0ID0gImlkZW50aXR5IiwgYWVzKCBzaGFwZSA9IHR5cGUsIGNvbG9yID0gdHlwZSksIHNpemUgPSAzKSArDQogIGdlb21fbGluZSgpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkgKw0KICB4bGFiKCJFY29yZWdpb24iKSArDQogIHlsYWIoInByb3BvcnRpb24gaW4gY2VsbCIpICsgDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLA0KICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCkpICsNCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpKQ0KYGBgDQoNCkEgc2ltaWxhciBjb21wYXJpc29uIGJ5IHN0YXRlIHdhcyBjb25zdHJ1Y3RlZCBiZWxvdy4NCmBgYHtyIHN0YXRlX3Byb3BzX3BvcCwgZXZhbD1GQUxTRSwgaW5jbHVkZT1UUlVFLCBtZXNzYWdlPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvcGZyYW1lLnJkYSIpDQoNCnBmcmFtZV9zdGF0ZSA8LSBwZnJhbWUgJT4lDQogIGdyb3VwX2J5KHN0YXRlKSAlPiUNCiAgc3VtbWFyaXNlKG5fbGFrZXMgPSBzdW0obl9sYWtlcykpICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZShwcm9wX2NlbGwgPSByb3VuZChuX2xha2VzL3N1bShuX2xha2VzKSwgNykpICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZSh0eXBlID0gJ3BvcHVsYXRpb24nKQ0KDQpzYXZlKHBmcmFtZV9zdGF0ZSwgZmlsZSA9ICJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9wZnJhbWVfc3RhdGUucmRhIikNCmBgYA0KDQpgYGB7ciBzdGF0ZV9wcm9wc19zYW1wbGUsIGV2YWw9RkFMU0UsIGluY2x1ZGU9VFJVRSwgbWVzc2FnZT1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL3NhbXBfcHJvcHMucmRhIikNCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL3NhbXBfcHJvcHMucmRhIikNCg0Kc2FtcF9wcm9wc19zdGF0ZSA8LSBzYW1wX3Byb3BzICU+JQ0KICBncm91cF9ieShzdGF0ZSkgJT4lDQogIHN1bW1hcmlzZShuX2xha2VzID0gc3VtKG5fbGFrZXMpKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUocHJvcF9jZWxsID0gcm91bmQobl9sYWtlcy9zdW0obl9sYWtlcyksIDcpKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUodHlwZSA9ICdzYW1wbGUnKQ0KDQpzYXZlKHNhbXBfcHJvcHNfc3RhdGUsIGZpbGUgPSAiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvc2FtcF9wcm9wc19zdGF0ZS5yZGEiKQ0KYGBgDQoNCmBgYHtyIGNvbXBhcmVfc3RhdGVfc2FtcGxlX3BvcF9jZWxscywgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD0xMH0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL3BmcmFtZV9zdGF0ZS5yZGEiKQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvc2FtcF9wcm9wc19zdGF0ZS5yZGEiKQ0KDQpwZnJhbWVfc3RhdGUgJT4lDQogIGJpbmRfcm93cyhzYW1wX3Byb3BzX3N0YXRlKSAlPiUNCiAgZ2dwbG90KG1hcHBpbmcgPSBhZXMoeCA9IHN0YXRlLCB5ID0gcHJvcF9jZWxsLCBncm91cCA9IHR5cGUsIGxpbmV0eXBlID0gdHlwZSkpICsNCiAgZ2VvbV9wb2ludChzdGF0ID0gImlkZW50aXR5IiwgYWVzKHNoYXBlID0gdHlwZSwgY29sb3IgPSB0eXBlKSkgKw0KICBnZW9tX2xpbmUoKSArDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSkpICsNCiAgeGxhYigiU3RhdGUiKSArDQogIHlsYWIoInByb3BvcnRpb24gaW4gY2VsbCIpDQpgYGANCg0KRmluYWxseSwgYSBjb21wYXJpc29uIGJ5IGxha2Ugc2l6ZSBjYXRlZ29yeSBpcyBzaG93biBiZWxvdy4gTm90ZSB0aGF0IHNtYWxsIGxha2VzIHdlcmUgdW5kZXItc2FtcGxlZCByZWxhdGl2ZSB0byBsYXJnZXIgbGFrZXMgYnkgZGVzaWduLg0KYGBge3Igc2l6ZV9wcm9wc19wb3AsIGV2YWw9RkFMU0UsIGluY2x1ZGU9VFJVRSwgbWVzc2FnZT1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL3BmcmFtZS5yZGEiKQ0KDQpwZnJhbWVfc2l6ZSA8LSBwZnJhbWUgJT4lDQogIGdyb3VwX2J5KHNpemVfY2F0KSAlPiUNCiAgc3VtbWFyaXNlKG5fbGFrZXMgPSBzdW0obl9sYWtlcykpICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZShwcm9wX2NlbGwgPSByb3VuZChuX2xha2VzL3N1bShuX2xha2VzKSwgNykpICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZSh0eXBlID0gJ3BvcHVsYXRpb24nKQ0KDQpzYXZlKHBmcmFtZV9zaXplLCBmaWxlID0gIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL3BmcmFtZV9zaXplLnJkYSIpDQpgYGANCg0KYGBge3Igc2l6ZV9wcm9wc19zYW1wbGUsIGV2YWw9RkFMU0UsIGluY2x1ZGU9VFJVRSwgbWVzc2FnZT1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL3NhbXBfcHJvcHMucmRhIikNCg0Kc2FtcF9wcm9wc19zaXplIDwtIHNhbXBfcHJvcHMgJT4lDQogIGdyb3VwX2J5KHNpemVfY2F0KSAlPiUNCiAgc3VtbWFyaXNlKG5fbGFrZXMgPSBzdW0obl9sYWtlcykpICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZShwcm9wX2NlbGwgPSByb3VuZChuX2xha2VzL3N1bShuX2xha2VzKSwgNykpICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZSh0eXBlID0gJ3NhbXBsZScpDQoNCnNhdmUoc2FtcF9wcm9wc19zaXplLCBmaWxlID0gIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL3NhbXBfcHJvcHNfc2l6ZS5yZGEiKQ0KYGBgDQoNCmBgYHtyIGNvbXBhcmVfc2l6ZV9zYW1wbGVfcG9wX2NlbGxzLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTZ9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9wZnJhbWVfc2l6ZS5yZGEiKQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvc2FtcF9wcm9wc19zaXplLnJkYSIpDQoNCnBmcmFtZV9zaXplICU+JQ0KICBiaW5kX3Jvd3Moc2FtcF9wcm9wc19zaXplKSAlPiUNCiAgZ2dwbG90KG1hcHBpbmcgPSBhZXMoeCA9IHNpemVfY2F0LCB5ID0gcHJvcF9jZWxsLCBncm91cCA9IHR5cGUsIGxpbmV0eXBlID0gdHlwZSkpICsNCiAgZ2VvbV9wb2ludChzdGF0ID0gImlkZW50aXR5IiwgYWVzKCBzaGFwZSA9IHR5cGUsIGNvbG9yID0gdHlwZSkpICsNCiAgZ2VvbV9saW5lKCkgKw0KICB0aGVtZV90aWR5YmF5ZXMoKSArDQogIHhsYWIoIlNpemUgY2F0ZWdvcnkiKSArDQogIHlsYWIoInByb3BvcnRpb24gaW4gY2VsbCIpDQpgYGANCg0KIyMgU2FtcGxlLWJhc2VkIGVzdGltYXRlcw0KVGhlIG92ZXJhbGwgbWVhbiBhbmQgc3RhbmRhcmQgZGV2aWF0aW9uIGZvciBOMk8gaW4gdGhlIHNhbXBsZToNCmBgYHtyIHNhbXBsZV9zdW1tYXJ5X24yb30NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2RmX21vZGVsLnJkYSIpDQoNCmRmX21vZGVsICU+JQ0KICBzdW1tYXJpc2UobWVhbiA9IG1lYW4objJvKSwNCiAgICAgICAgICAgICBzZCA9IHNkKG4ybykpICU+JQ0KICBwcmludCgpDQpgYGANCg0KVGhlIHNhbWUgc3VtbWFyeSBmb3IgZXF1aWxpYnJpdW0gTjJPOg0KYGBge3Igc2FtcGxlX3N1bW1hcnlfbjJvZXF9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZl9tb2RlbC5yZGEiKQ0KDQpkZl9tb2RlbCAlPiUNCiAgc3VtbWFyaXNlKG1lYW4gPSBtZWFuKG4yb19lcSksDQogICAgICAgICAgICAgc2QgPSBzZChuMm9fZXEpKSAlPiUNCiAgcHJpbnQoKQ0KYGBgDQoNClRoZSBzYXR1cmF0aW9uIHJhdGlvIChpLmUuLCBOMk8gLyBOMk8tZXEpOg0KYGBge3Igc2FtcGxlX3N1bW1hcnlfbjJvc2F0fQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvZGZfbW9kZWwucmRhIikNCg0KZGZfbW9kZWwgJT4lDQogIHN1bW1hcmlzZShtZWFuID0gbWVhbihuMm8gLyBuMm9fZXEpLA0KICAgICAgICAgICAgIHNkID0gc2QobjJvIC8gbjJvX2VxKSkgJT4lDQogIHByaW50KCkNCmBgYA0KDQpGaW5hbGx5LCByb3VnaGx5IDY3JSBvZiBsYWtlcyBpbiB0aGUgc2FtcGxlIHdlcmUgdW5kZXJzYXR1cmF0ZWQgKGkuZS4sIHNhdHVyYXRpb24gcmF0aW8gPCAxKToNCmBgYHtyIHNhbXBsZV9zdW1tYXJ5X3Byb3BzYXR9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZl9tb2RlbC5yZGEiKQ0KDQpkZl9tb2RlbCAlPiUNCiAgc3VtbWFyaXNlKHByb3BfdW5kZXJzYXQgPSBzdW0oKG4ybyAvIG4yb19lcSkgPCAxKSAvIDk4NCkgJT4lDQogIHByaW50KCkNCmBgYA0KDQpVc2luZyBvbmx5IHRoZSBzYW1wbGUgb2JzZXJ2YXRpb25zLCBhIHBsb3Qgd2FzIGNvbnN0cnVjdGVkIGJlbG93IG9mIHRoZSBvdmVyYWxsIG1lYW4gKGRhc2hlZCBsaW5lKSBhbG9uZyB3aXRoIHRoZSBlY29yZWdpb24tc3BlY2lmaWMgbWVhbnMgKGJsYWNrIGNpcmNsZXMpLiBUaGUgc2hhZGVkIGFyZWFzIGluZGljYXRlICsvLSAxIHN0YW5kYXJkIGRldmlhdGlvbi4gTmVpdGhlciBkaXNzb2x2ZWQgTjJPIG5vciB0aGUgc2F0dXJhdGlvbiByYXRpbyB3ZXJlIGNsZWFybHkgc3RydWN0dXJlZCBieSBlY29yZWdpb24gaW4gdGhlIHNhbXBsZSwgYnV0IHRoZXJlIGRpZCBhcHBlYXIgdG8gYmUgc29tZSBzdHJ1Y3R1cmUgaW4gdGhlIGVxdWlsaWJyaXVtIE4yTyBvYnNlcnZhdGlvbnMuDQpgYGB7ciBzYW1wbGVfc3VtbWFyeV9lY28sIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2RmX21vZGVsLnJkYSIpDQoNCnAxIDwtIGRmX21vZGVsICU+JQ0KICBncm91cF9ieShXU0E5KSAlPiUNCiAgc3VtbWFyaXNlKG1lYW4gPSBtZWFuKG4ybyksDQogICAgICAgICAgICAgc2QgPSBzZCggbjJvKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IFdTQTksIHkgPSBtZWFuLCBncm91cCA9IDEpKSArDQogIGdlb21fcmliYm9uKGFlcyh5bWluID0gbWVhbiAtIHNkLCB5bWF4ID0gbWVhbiArIHNkLCB4ID0gV1NBOSksIGZpbGwgPSAnbGlnaHRncmV5JywgYWxwaGEgPSAuNykrDQogIGdlb21fbGluZShhZXMoeCA9IFdTQTksIHkgPSBtZWFuKSkrDQogIGdlb21fcG9pbnQoKSsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gOC43MiwgbGluZXR5cGUgPSAnZGFzaGVkJykgKw0KICB0aGVtZV90aWR5YmF5ZXMoKSArIA0KICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpKSArIA0KICB5bGFiKCIiKSArDQogIGdndGl0bGUoIk4yTyIpDQoNCnAyIDwtIGRmX21vZGVsICU+JQ0KICBncm91cF9ieShXU0E5KSAlPiUNCiAgc3VtbWFyaXNlKG1lYW4gPSBtZWFuKG4yb19lcSksDQogICAgICAgICAgICAgc2QgPSBzZChuMm9fZXEpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gV1NBOSwgeSA9IG1lYW4sIGdyb3VwID0gMSkpICsNCiAgZ2VvbV9yaWJib24oYWVzKHltaW4gPSBtZWFuIC0gc2QsIHltYXggPSBtZWFuICsgc2QsIHggPSBXU0E5KSwgZmlsbCA9ICdsaWdodGdyZXknLCBhbHBoYSA9IC43KSsNCiAgZ2VvbV9saW5lKGFlcyh4ID0gV1NBOSwgeSA9IG1lYW4pKSsNCiAgZ2VvbV9wb2ludCgpKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA3LjQ4LCBsaW5ldHlwZSA9ICdkYXNoZWQnKSArDQogIHRoZW1lX3RpZHliYXllcygpICsgDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCkpICsNCiAgeWxhYigiU2FtcGxlIG1lYW4iKSArDQogIGdndGl0bGUoIk4yTyBlcXVpbGlicml1bSIpDQoNCnAzIDwtIGRmX21vZGVsICU+JQ0KICBncm91cF9ieShXU0E5KSAlPiUNCiAgc3VtbWFyaXNlKG1lYW4gPSBtZWFuKG4ybyAvIG4yb19lcSksDQogICAgICAgICAgICAgc2QgPSBzZChuMm8gLyBuMm9fZXEpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gV1NBOSwgeSA9IG1lYW4sIGdyb3VwID0gMSkpICsNCiAgZ2VvbV9yaWJib24oYWVzKHltaW4gPSBtZWFuIC0gc2QsIHltYXggPSBtZWFuICsgc2QsIHggPSBXU0E5KSwgZmlsbCA9ICdsaWdodGdyZXknLCBhbHBoYSA9IC43KSsNCiAgZ2VvbV9saW5lKGFlcyh4ID0gV1NBOSwgeSA9IG1lYW4pKSsNCiAgZ2VvbV9wb2ludCgpKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxLjE3LCBsaW5ldHlwZSA9ICdkYXNoZWQnKSArDQogIHRoZW1lX3RpZHliYXllcygpICsgIA0KICB4bGFiKCJFY29yZWdpb24iKSArDQogIHlsYWIoIiIpICsNCiAgZ2d0aXRsZSgiTjJPIHNhdHVyYXRpb24gcmF0aW8iKQ0KDQpncmlkLmFycmFuZ2UocDEsIHAyLCBwMykNCmBgYA0KDQpUaGUgc2FtZSBzdW1tYXJ5IGJ5IHN0YXRlIGlzIGJlbG93Lg0KYGBge3Igc2FtcGxlX3N1bW1hcnlfc3RhdGUsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2RmX21vZGVsLnJkYSIpDQoNCnAxIDwtIGRmX21vZGVsICU+JQ0KICBncm91cF9ieShzdGF0ZSkgJT4lDQogIHN1bW1hcmlzZShtZWFuID0gbWVhbihuMm8pLA0KICAgICAgICAgICAgIHNkID0gc2QoIG4ybykpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBzdGF0ZSwgeSA9IG1lYW4sIGdyb3VwID0gMSkpICsNCiAgZ2VvbV9yaWJib24oYWVzKHltaW4gPSBtZWFuIC0gc2QsIHltYXggPSBtZWFuICsgc2QsIHggPSBzdGF0ZSksIA0KICAgICAgICAgICAgICBmaWxsID0gJ2xpZ2h0Z3JleScsIA0KICAgICAgICAgICAgICBhbHBoYSA9IC43KSArDQogIGdlb21fbGluZShhZXMoeCA9IHN0YXRlLCB5ID0gbWVhbikpKw0KICBnZW9tX3BvaW50KCkrDQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDguNzIsIGxpbmV0eXBlID0gJ2Rhc2hlZCcpICsgDQogIHRoZW1lX3RpZHliYXllcygpICsgDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCkpICsgDQogIHlsYWIoIiIpICsNCiAgZ2d0aXRsZSgiTjJPIikNCg0KcDIgPC0gZGZfbW9kZWwgJT4lDQogIGdyb3VwX2J5KHN0YXRlKSAlPiUNCiAgc3VtbWFyaXNlKG1lYW4gPSBtZWFuKG4yb19lcSksDQogICAgICAgICAgICAgc2QgPSBzZChuMm9fZXEpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gc3RhdGUsIHkgPSBtZWFuLCBncm91cCA9IDEpKSArDQogIGdlb21fcmliYm9uKGFlcyh5bWluID0gbWVhbiAtIHNkLCB5bWF4ID0gbWVhbiArIHNkLCB4ID0gc3RhdGUpLCANCiAgICAgICAgICAgICAgZmlsbCA9ICdsaWdodGdyZXknLCANCiAgICAgICAgICAgICAgYWxwaGEgPSAuNykgKw0KICBnZW9tX2xpbmUoYWVzKHggPSBzdGF0ZSwgeSA9IG1lYW4pKSsNCiAgZ2VvbV9wb2ludCgpKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA3LjQ4LCBsaW5ldHlwZSA9ICdkYXNoZWQnKSArDQogIHRoZW1lX3RpZHliYXllcygpICsgDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCkpICsNCiAgeWxhYigiU2FtcGxlIG1lYW4iKSArDQogIGdndGl0bGUoIk4yTyBlcXVpbGlicml1bSIpDQoNCnAzIDwtIGRmX21vZGVsICU+JQ0KICBncm91cF9ieShzdGF0ZSkgJT4lDQogIHN1bW1hcmlzZShtZWFuID0gbWVhbihuMm8gLyBuMm9fZXEpLA0KICAgICAgICAgICAgIHNkID0gc2QobjJvIC8gbjJvX2VxKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHN0YXRlLCB5ID0gbWVhbiwgZ3JvdXAgPSAxKSkgKw0KICBnZW9tX3JpYmJvbihhZXMoeW1pbiA9IG1lYW4gLSBzZCwgeW1heCA9IG1lYW4gKyBzZCwgeCA9IHN0YXRlKSwgDQogICAgICAgICAgICAgIGZpbGwgPSAnbGlnaHRncmV5JywgDQogICAgICAgICAgICAgIGFscGhhID0gLjcpKw0KICBnZW9tX2xpbmUoYWVzKHggPSBzdGF0ZSwgeSA9IG1lYW4pKSsNCiAgZ2VvbV9wb2ludCgpKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxLjE3LCBsaW5ldHlwZSA9ICdkYXNoZWQnKSArDQogIHRoZW1lX3RpZHliYXllcygpICsgDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUpKSArIA0KICB4bGFiKCJTdGF0ZSIpICsNCiAgeWxhYigiIikgKw0KICBnZ3RpdGxlKCJOMk8gc2F0dXJhdGlvbiByYXRpbyIpDQoNCmdyaWQuYXJyYW5nZShwMSwgcDIsIHAzKQ0KYGBgDQoNCkZpbmFsbHksIHRoZSBzYW1lIHN1bW1hcnkgYnkgc2l6ZSBjYXRlZ29yeToNCmBgYHtyIHNhbXBsZV9zdW1tYXJ5X3NpemUsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2RmX21vZGVsLnJkYSIpDQoNCnAxIDwtIGRmX21vZGVsICU+JQ0KICBncm91cF9ieShzaXplX2NhdCkgJT4lDQogIHN1bW1hcmlzZShtZWFuID0gbWVhbihuMm8pLA0KICAgICAgICAgICAgIHNkID0gc2QoIG4ybykpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBzaXplX2NhdCwgeSA9IG1lYW4sIGdyb3VwID0gMSkpICsNCiAgZ2VvbV9yaWJib24oYWVzKHltaW4gPSBtZWFuIC0gc2QsIHltYXggPSBtZWFuICsgc2QsIHggPSBzaXplX2NhdCksIGZpbGwgPSAnbGlnaHRncmV5JywgYWxwaGEgPSAuNykrDQogIGdlb21fbGluZShhZXMoeCA9IHNpemVfY2F0LCB5ID0gbWVhbikpKw0KICBnZW9tX3BvaW50KCkrDQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDguNzIsIGxpbmV0eXBlID0gJ2Rhc2hlZCcpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkgKyANCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSkgKyANCiAgeWxhYigiIikgKw0KICBnZ3RpdGxlKCJOMk8iKQ0KDQpwMiA8LSBkZl9tb2RlbCAlPiUNCiAgZ3JvdXBfYnkoc2l6ZV9jYXQpICU+JQ0KICBzdW1tYXJpc2UobWVhbiA9IG1lYW4objJvX2VxKSwNCiAgICAgICAgICAgICBzZCA9IHNkKG4yb19lcSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBzaXplX2NhdCwgeSA9IG1lYW4sIGdyb3VwID0gMSkpICsNCiAgZ2VvbV9yaWJib24oYWVzKHltaW4gPSBtZWFuIC0gc2QsIHltYXggPSBtZWFuICsgc2QsIHggPSBzaXplX2NhdCksIGZpbGwgPSAnbGlnaHRncmV5JywgYWxwaGEgPSAuNykrDQogIGdlb21fbGluZShhZXMoeCA9IHNpemVfY2F0LCB5ID0gbWVhbikpKw0KICBnZW9tX3BvaW50KCkrDQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDcuNDgsIGxpbmV0eXBlID0gJ2Rhc2hlZCcpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkgKyANCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSkgKw0KICB5bGFiKCJTYW1wbGUgbWVhbiIpICsNCiAgZ2d0aXRsZSgiTjJPIGVxdWlsaWJyaXVtIikNCg0KcDMgPC0gZGZfbW9kZWwgJT4lDQogIGdyb3VwX2J5KHNpemVfY2F0KSAlPiUNCiAgc3VtbWFyaXNlKG1lYW4gPSBtZWFuKG4ybyAvIG4yb19lcSksDQogICAgICAgICAgICAgc2QgPSBzZChuMm8gLyBuMm9fZXEpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gc2l6ZV9jYXQsIHkgPSBtZWFuLCBncm91cCA9IDEpKSArDQogIGdlb21fcmliYm9uKGFlcyh5bWluID0gbWVhbiAtIHNkLCB5bWF4ID0gbWVhbiArIHNkLCB4ID0gc2l6ZV9jYXQpLCBmaWxsID0gJ2xpZ2h0Z3JleScsIGFscGhhID0gLjcpKw0KICBnZW9tX2xpbmUoYWVzKHggPSBzaXplX2NhdCwgeSA9IG1lYW4pKSsNCiAgZ2VvbV9wb2ludCgpKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxLjE3LCBsaW5ldHlwZSA9ICdkYXNoZWQnKSArDQogIHRoZW1lX3RpZHliYXllcygpICsgDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUpKSArIA0KICB4bGFiKCJTaXplIGNsYXNzIikgKw0KICB5bGFiKCIiKSArDQogIGdndGl0bGUoIk4yTyBzYXR1cmF0aW9uIHJhdGlvIikNCg0KZ3JpZC5hcnJhbmdlKHAxLCBwMiwgcDMpDQpgYGANCg0KIyMgU2FtcGxlIGRhdGEgZXhwbG9yYXRpb24NCkJlbG93LCB0aGUgZW1waXJpY2FsIGRpc3RyaWJ1dGlvbiBvZiBOMk8gb2JzZXJ2YXRpb25zIGluIHRoZSBzYW1wbGUgd2FzIHN1bW1hcml6ZWQgdXNpbmcgYSBkZW5zaXR5IGFuZCBydWcgcGxvdCBiZWxvdy4gTm90ZSB0aGUgbmF0dXJhbCBsb2cgc2NhbGUgb2YgdGhlIHggYXhpcy4gQm90aCB0aGUgTjJPIGFuZCBlcXVpbGlicml1bSBOMk8gZGF0YSBoYWQgY29uc2lkZXJhYmxlIHJpZ2h0IHNrZXcgZXZlbiBhZnRlciB0aGUgbG9nIHRyYW5zZm9ybWF0aW9uLCB3aGljaCB3YXMgbm90IHVuZXhwZWN0ZWQgYW5kIGhhcyBiZWVuIG5vdGVkIGluIG90aGVyIHN0dWRpZXMgW0BXZWJiX2V0YWxfMjAxOV0uIFRoZSBzYXR1cmF0aW9uIHJhdGlvIHdhcyBhbHNvIHNrZXdlZCBzaW5jZSBpdCB3YXMgZGVyaXZlZCBmcm9tIHRoZSBvdGhlciB0d28gb2JzZXJ2ZWQgdmFyaWFibGVzIChpLmUuLCBzYXRfcmF0aW8gPSBuMm8gLyBuMm9fZXEpLg0KYGBge3Igc3VtbWFyeV9OMk8sIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9NSwgbWVzc2FnZT1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2RmX21vZGVsLnJkYSIpDQoNCnAxIDwtIGRmX21vZGVsICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBuMm8pKSArDQogIGdlb21fYm94cGxvdChhZXMoeCA9IG4ybywgeSA9IC0wLjUpLCBvdXRsaWVyLnNoYXBlID0gTkEsIGFscGhhID0gMC43KSArIA0KICBnZW9tX2RlbnNpdHkoYWVzKHggPSBuMm8pKSArDQogIGdlb21fcnVnKGFlcyh4ID0gbjJvKSwgc2hvdy5sZWdlbmQgPSBGICkgKw0KICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTIpKSArDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciLCBicmVha3MgPSBjKDAsIDUsIDEwLCAyNSwgNTAsIDE1MCkpICsNCiAgeWxhYigiZGVuc2l0eSIpICsNCiAgeGxhYigiTjJPIChubW9sL0wpIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKSArDQogIHRoZW1lKGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpKQ0KDQpwMiA8LSBkZl9tb2RlbCAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbjJvX2VxKSkgKw0KICBnZW9tX2JveHBsb3QoYWVzKHggPSBuMm9fZXEsIHkgPSAtMC41KSwgb3V0bGllci5zaGFwZSA9IE5BLCBhbHBoYSA9IDAuNykgKyANCiAgZ2VvbV9kZW5zaXR5KGFlcyh4ID0gbjJvX2VxKSkgKw0KICBnZW9tX3J1ZyhhZXMoeCA9IG4yb19lcSksIHNob3cubGVnZW5kID0gRiApICsNCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgKw0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICB5bGFiKCJkZW5zaXR5IikgKw0KICB4bGFiKCJFcXVpbGlicml1bSBOMk8gKG5tb2wvTCkiKSArDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCkpDQoNCnAzIDwtIGRmX21vZGVsICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBuMm8gLyBuMm9fZXEpKSArDQogIGdlb21fYm94cGxvdChhZXMoeCA9IG4ybyAvIG4yb19lcSwgeSA9IC0wLjUpLCBvdXRsaWVyLnNoYXBlID0gTkEsIGFscGhhID0gMC43KSArIA0KICBnZW9tX2RlbnNpdHkoYWVzKHggPSBuMm8gLyBuMm9fZXEpKSArDQogIGdlb21fcnVnKGFlcyh4ID0gbjJvIC8gbjJvX2VxKSwgc2hvdy5sZWdlbmQgPSBGICkgKw0KICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTIpKSArDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciLCBicmVha3MgPSBjKDAsIDEsIDUsIDEwLCAyMCkpICsNCiAgeWxhYigiZGVuc2l0eSIpICsNCiAgeGxhYigiTjJPIHNhdHVyYXRpb24gcmF0aW8iKSArDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCkpDQoNCmdyaWQuYXJyYW5nZShwMSwgcDIsIHAzKQ0KYGBgDQoNCkJlbG93IGFyZSBwbG90cyBvZiBOMk8gdnMuIE5PMy4gVGhlIGZpcnN0IHBsb3Qgc2hvd3MgbG9nKE4yTykgdnMuIGxvZyhOTzMpLCBhcyB3ZWxsIGFzIHRoZSBvcmRpbmFsIGNhdGVnb3JpZXMgYXNzaWduZWQgdG8gTk8zICh2ZXJ0aWNhbCBsaW5lcykuIFRoZSBsZWZ0bW9zdCB2ZXJ0aWNhbCBsaW5lIGlzIGRhc2hlZCBhbmQgc2VwYXJhdGVzIHRoZSBOTzMgb2JzZXJ2YXRpb25zIGJlbG93IHRoZSBkZXRlY3Rpb24gbGltaXQuDQpgYGB7ciBzdW1tYXJ5X04yT192c19OTzMsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NiwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2RmX21vZGVsLnJkYSIpDQoNCmRmX21vZGVsICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBsb2cobm8zKSwgeSA9IGxvZyhuMm8pKSkgKw0KICBnZW9tX3BvaW50KHNob3cubGVnZW5kID0gRikgKw0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG9lc3MiLCBzcGFuID0gMikgKw0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAtNy41LCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IC01LjUpICsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gLTMuNSkgKw0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAtMS41KSArDQogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMikpICsNCiAgdGhlbWVfYncoKQ0KYGBgDQoNCkluIHRoZSBwbG90IGFib3ZlLCB0aGUgdHJlbmQgaXMgaW5jcmVhc2luZyBhbmQgbm9ubGluZWFyIG9uIHRoZSBsb2cgc2NhbGUuIFRoZSBpbmNyZWFzaW5nIHZhcmlhbmNlIGluIE4yTyBhbG9uZyB0aGUgTk8zIGdyYWRlaWVudCBzdWdnZXN0ZWQgYSBwb3RlbnRpYWwgbWVkaWF0b3Igb2YgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIE5PMyBvbiBOMk8uIEJlbG93IGFyZSBwbG90cyBvZiBOMk8gdnMuIE5PMyBmb3IgNiBxdWFudGlsZXMgb2YgdGhlIHN1cmZhY2UgdGVtcGVyYXR1cmUgbWVhc3VyZW1lbnRzIChxdWFudGlsZXMgaW5jcmVhc2luZyBmcm9tIDEgdG8gNikuIFRoaXMgcGxvdCBiZWxvdyBzdWdnZXN0ZWQgdGhhdCB0aGUgTk8zIGVmZmVjdCBvbiBOMk8gbWF5IGhhdmUgYmVlbiBzdHJvbmdlciBpbiBsYWtlcyB3aXRoIGhpZ2hlciBvYnNlcnZlZCB0ZW1wZXJhdHVyZXMuDQpgYGB7ciBzdW1tYXJ5X04yT192c19OTzNfc3VyZnRlbXAsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD01LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2RmX21vZGVsLnJkYSIpDQoNCmRmX21vZGVsICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBsb2cobm8zKSwgeSA9IGxvZyhuMm8pKSkgKw0KICBnZW9tX3BvaW50KHNob3cubGVnZW5kID0gRikgKw0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG9lc3MiLCBzcGFuID0gMikgKw0KICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTIpKSArDQogIGZhY2V0X3dyYXAofiBhcy5mYWN0b3IobnRpbGUoc3VyZnRlbXAsIDYpKSkgKw0KICB0aGVtZV9idygpDQpgYGANCg0KVGhlIG5leHQgcGxvdCBiZWxvdyBzaG93cyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gTjJPIGFuZCBOTzMgYXQgNiBkaWZmZXJlbnQgcXVhbnRpbGVzIChpbmNyZWFzaW5nIDEgdG8gNikgb2YgdGhlIGxvZy1zY2FsZWQgbGFrZSBzdXJmYWNlIGFyZWEgZXN0aW1hdGVzLg0KYGBge3Igc3VtbWFyeV9OMk9fdnNfTk8zX2xvZ2FyZWEsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD01LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2RmX21vZGVsLnJkYSIpDQoNCmRmX21vZGVsICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBsb2cobm8zKSwgeSA9IGxvZyhuMm8pKSkgKw0KICBnZW9tX3BvaW50KHNob3cubGVnZW5kID0gRikgKw0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG9lc3MiLCBzcGFuID0gMikgKw0KICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTIpKSArDQogIGZhY2V0X3dyYXAofiBhcy5mYWN0b3IobnRpbGUobG9nX2FyZWEsIDYpKSkgKw0KICB0aGVtZV9idygpDQpgYGANCg0KU2ltaWxhciBwbG90cyBhcmUgYmVsb3csIGJ1dCB3aXRoIE5PMyBleHByZXNzZWQgYXMgYW4gb3JkZXJlZCBjYXRlZ29yaWNhbCB2YXJpYWJsZSB3aXRoIDUgbGV2ZWxzLiBUaGUgcG9zaXRpdmUgYW5kIG1vbm90b25pYyB0cmVuZHMgYXJlYSBzaW1pbGFyIHRvIHRoZSBwcmV2aW91cyBwbG90cyB3aGVyZSBOTzMgd2FzIHRyZWF0ZWQgYXMgY29udGludW91cy4gTm90ZSB0aGUgbGFyZ2UgbnVtYmVyIG9mIG9ic2VydmF0aW9ucyBpbiB0aGUgZmlyc3QgTk8zIGNhdGVnb3J5IChubzNfY2F0ID0gMSkuIFRoaXMgY2F0ZWdvcnkgcmVwcmVzZW50ZWQgYWxsIG9mIHRoZSBjZW5zb3JlZCBvYnNlcnZhdGlvbnMgZm9yIE5PMywgd2hpY2ggd2FzIG1vc3Qgb2YgdGhlIGRhdGEuDQpgYGB7ciBzdW1tYXJ5X04yT192c19OTzNjYXQsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NiwgbWVzc2FnZT1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2RmX21vZGVsLnJkYSIpDQoNCmRmX21vZGVsICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBubzNfY2F0LCB5ID0gbG9nKG4ybyksIGNvbG9yID0gMSkpICsNCiAgZ2VvbV9wb2ludCggcG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXJkb2RnZSgpLCBzaG93LmxlZ2VuZCA9IEYgKSArDQogIGdlb21fYm94cGxvdChvdXRsaWVyLnNoYXBlID0gTkEsIG5vdGNoID0gVFJVRSwgY29sb3IgPSAiYmxhY2siLCBhbHBoYSA9IDAuNykgKw0KICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTIpKSArDQogIHRoZW1lX2J3KCkNCmBgYA0KDQpgYGB7ciBzdW1tYXJ5X04yT192c19OTzNjYXRfc3VyZnRlbXAsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD01LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2RmX21vZGVsLnJkYSIpDQoNCmRmX21vZGVsICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBubzNfY2F0LCB5ID0gbG9nKG4ybyksIGNvbG9yID0gMSkpICsNCiAgZ2VvbV9wb2ludCggcG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXJkb2RnZSgpLCBzaG93LmxlZ2VuZCA9IEYgKSArDQogIGdlb21fYm94cGxvdChvdXRsaWVyLnNoYXBlID0gTkEsIGNvbG9yID0gImJsYWNrIiwgYWxwaGEgPSAwLjcpICsNCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgKw0KICBmYWNldF93cmFwKH4gYXMuZmFjdG9yKG50aWxlKHN1cmZ0ZW1wLCA2KSkpICsNCiAgdGhlbWVfYncoKQ0KYGBgDQoNCmBgYHtyIHN1bW1hcnlfTjJPX3ZzX05PM2NhdF9sb2dhcmVhLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NSwgZmlnLndpZHRoPTgsIG1lc3NhZ2U9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZl9tb2RlbC5yZGEiKQ0KDQpkZl9tb2RlbCAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbm8zX2NhdCwgeSA9IGxvZyhuMm8pLCBjb2xvciA9IDEpKSArDQogIGdlb21fcG9pbnQoIHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyZG9kZ2UoKSwgc2hvdy5sZWdlbmQgPSBGICkgKw0KICBnZW9tX2JveHBsb3Qob3V0bGllci5zaGFwZSA9IE5BLCBjb2xvciA9ICJibGFjayIsIGFscGhhID0gMC43KSArDQogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMikpICsNCiAgZmFjZXRfd3JhcCh+IGFzLmZhY3RvcihudGlsZShsb2dfYXJlYSwgNikpKSArDQogIHRoZW1lX2J3KCkNCmBgYA0KDQpCZWxvdyBpcyBhIHBsb3Qgb2YgbG9nKE4yTykgdnMuIGxvZyhOTzMpIGJ5IGVjb3JlZ2lvbiwgd2hpY2ggc3VnZ2VzdGVkIHRoYXQgdGhlIE5PMyBlZmZlY3Qgb24gTjJPIG1heSBoYXZlIHZhcmllZCBieSBlY29yZWdpb24uDQpgYGB7ciBzdW1tYXJ5X04yT192c19OTzNfZWNvcmVnaW9uLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTgsIG1lc3NhZ2U9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZl9tb2RlbC5yZGEiKQ0KDQpkZl9tb2RlbCAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbG9nKG5vMyksIHkgPSBsb2cobjJvKSkpICsNCiAgZ2VvbV9wb2ludChzaG93LmxlZ2VuZCA9IEYpICsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgc3BhbiA9IDIpICsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gLTcuNSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAtNS41KSArDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IC0zLjUpICsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gLTEuNSkgKw0KICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTIpKSArDQogIGZhY2V0X3dyYXAofiBXU0E5KSArDQogIHRoZW1lX2J3KCkNCmBgYA0KDQpCZWxvdyBpcyB0aGUgc2FtZSBwbG90IGFzIGFib3ZlIGJ1dCBmb3IgdGhlIG9yZGVyZWQgY2F0ZWdvcmljYWwgdmVyc2lvbiBvZiBOTzMuDQpgYGB7ciBzdW1tYXJ5X04yT192c19OTzNjYXRfZWNvcmVnaW9uLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTgsIG1lc3NhZ2U9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZl9tb2RlbC5yZGEiKQ0KDQpkZl9tb2RlbCAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbm8zX2NhdCwgeSA9IGxvZyhuMm8pLCBjb2xvciA9IDEpKSArDQogIGdlb21fcG9pbnQoIHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyZG9kZ2UoKSwgc2hvdy5sZWdlbmQgPSBGICkgKw0KICBnZW9tX2JveHBsb3QoYWVzKHggPSBubzNfY2F0LCB5ID0gbG9nKG4ybykpLCANCiAgICAgICAgICAgICAgIG91dGxpZXIuc2hhcGUgPSBOQSwgDQogICAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIsIA0KICAgICAgICAgICAgICAgYWxwaGEgPSAwLjcpICsgDQogIGZhY2V0X3dyYXAofiBXU0E5KSArDQogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMikpICsNCiAgdGhlbWVfYncoKQ0KYGBgDQoNCkEgcGxvdCBiZWxvdyBzaG93cyB0cmVuZHMgYnkgc3RhdGUgd2l0aGluIGp1c3QgdGhlIFRlbXBlcmF0ZSBQbGFpbnMgKFRQTCkgZWNvcmVnaW9uLiBXaXRoaW4gc3RhdGVzLCB0aGUgbnVtYmVyIG9mIG9ic2VydmF0aW9ucyB3ZXJlIHJlbGF0aXZlbHkgc21hbGwsIGJ1dCB0aGUgdHJlbmRzIGFwcGVhcmVkIGNsb3NlciB0byBsaW5lYXIuDQpgYGB7ciBzdW1tYXJ5X04yT192c19OTzNfd3NhOXN0YXRlMywgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD04LCBtZXNzYWdlPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvZGZfbW9kZWwucmRhIikNCg0KZGZfbW9kZWwgJT4lDQogIGZpbHRlcihXU0E5ID09ICJUUEwiKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbG9nKG5vMyksIHkgPSBsb2cobjJvKSwgZ3JvdXAgPSBzdGF0ZSwgY29sb3IgPSBzdGF0ZSkpICsNCiAgZ2VvbV9wb2ludChzaG93LmxlZ2VuZCA9IEYpICsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc3BhbiA9IDIsIGFscGhhID0gMC4xKSArDQogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMikpICsNCiAgdGhlbWVfYncoKQ0KYGBgDQoNCiMgTW9kZWwgZml0dGluZw0KVGhlIGZpcnN0IHJlZ3Jlc3Npb24gbW9kZWwgd2FzIGNvbnN0cnVjdGVkIHRvIGVzdGltYXRlIHRoZSBqb2ludCBkaXN0cmlidXRpb24gb2YgbG9nLXRyYW5zZm9ybWVkIE4yTyBhbmQgZXF1aWxpYnJpdW0gTjJPIGNvbmRpdGlvbmFsIG9uIHRoZSB0aGUgZGVzaWduIGZhY3RvcnMuIEVhY2ggbG9nLXRyYW5zZm9ybWVkIG9ic2VydmF0aW9uLCAkaSBcaW4gMSwuLixOPTk4NCQsIGZvciBlYWNoIHJlc3BvbnNlLCAkcCBcaW4gMTpQPTIkLCB3YXMgYXNzdW1lZCB0byBiZSBkcmF3biBmcm9tIGEgbXVsdGl2YXJpYXRlIG5vcm1hbCBkaXN0cmlidXRpb24gd2l0aCB0aGUgcGFyYW1ldGVycyAkXG51JCBhbmQgJFxTaWdtYSQsIHdoZXJlICRcbnUkIGlzIHRoZSBtdWx0aXZhcmlhdGUgbWVhbiBlc3RpbWF0ZWQgY29uZGl0aW9uYWwgb24gdGhlIGRlc2lnbiBlZmZlY3RzIGFuZCAkXFNpZ21hJCBpcyBhIGNvdmFyaWFuY2UgbWF0cml4IGNvbnRhaW5pbmcgdGhlIG9ic2VydmF0aW9uLWxldmVsIHZhcmlhbmNlcyBhbmQgcmVzaWR1YWwgY29ycmVsYXRpb246DQokJFkgXHNpbSBNVk4oXG51LCBcU2lnbWEpJCQNCg0KVGhlIG11bHRpdmFyaWF0ZSBtZWFuIGlzIGEgdmVjdG9yIG9mIG1lYW4gcGFyYW1ldGVycywgJFxudTpbXG11X3twPTF9LCBcbXVfe3A9Mn1dJCwgZm9yIGVhY2ggcmVzcG9uc2UuIEVhY2ggbWVhbiBpcyBmdXJ0aGVyIGRlZmluZWQgYnkgYSBsaW5lYXIgY29tYmluYXRpb24gb2YgcGFyYW1ldGVycyB3aGVyZSwgZm9yIGVhY2ggcmVzcG9uc2UgJHAkIGFuZCBvYnNlcnZhdGlvbiAkaSQ6DQoNCiQkXG11X3twaX0gPSBcYWxwaGFfezAocGkpfSArIFxhbHBoYV97MShwaWopfSArIFxhbHBoYV97MihwaWprKX0gKyBcYWxwaGFfezMocGlqa2wpfSBcXA0KXGFscGhhXzEgXHNpbSBNVk4oMCwgXExhbWJkYV8xKSBcXA0KXGFscGhhXzIgXHNpbSBNVk4oMCwgXExhbWJkYV8yKSBcXA0KXGFscGhhXzMgXHNpbSBNVk4oMCwgXExhbWJkYV8zKSQkDQoNClRoZSBsaW5lYXIgY29tYmluYXRpb24gb2YgcGFyYW1ldGVycyBkZWZpbmluZyAkXG11JCBhYm92ZSBpbmNsdWRlIGEgZml4ZWQgZ2xvYmFsIGludGVyY2VwdCwgJGFfMCQsIHRoYXQgaXMgZXN0aW1hdGVkIGRpcmVjdGx5IGZyb20gdGhlIGRhdGEsIGFuZCB0aHJlZSBzZXBhcmF0ZSwgbGF0ZW50IGdyb3VwLWxldmVsIGVmZmVjdHMgbWF0cmljZXMsICRcYWxwaGFfMSwgXGFscGhhXzIsIFxhbHBoYV8zJC4gVGhlIGdyb3VwIGVmZmVjdHMgd2VyZSBhc3N1bWVkIHRvIGJlIG11bHRpdmFyaWF0ZSBub3JtYWwgYW5kIGFyZSBjZW50ZXJlZCBvbiB6ZXJvIGluIG11bHRpdmFyaWF0ZSBzcGFjZS4gVGhlIHNwcmVhZCBvZiB0aGUgZWZmZWN0cyBhcm91bmQgemVybyBhcmUgZGV0ZXJtaW5lZCBieSBhIGNvdmFyaWFuY2UgbWF0cml4LCAkXExhbWJkYV8xLCBcTGFtYmRhXzIsIFx0ZXh0e29yIH0gXExhbWJkYV8zJCwgd2hpY2ggYXJlIGVzdGltYXRlZCBkaXJlY3RseSBmcm9tIHRoZSBkYXRhLiBUaGVzZSBjb3ZhcmlhbmNlIHRlcm1zIGFyZSBmdXJ0aGVyIGRlZmluZWQgd2hlcmU6DQoNCiQkXExhbWJkYSA9IFxiZWdpbntwbWF0cml4fSAxICYgXHRhdV97cD0xfSBcXCBcdGF1X3twPTJ9ICYgMSBcZW5ke3BtYXRyaXh9IFxjaGkgXGJlZ2lue3BtYXRyaXh9IDEgJiBcdGF1X3twPTF9IFxcIFx0YXVfe3A9Mn0gJiAxIFxlbmR7cG1hdHJpeH0kJA0KDQpUaGUgJFx0YXUkIHBhcmFtZXRlcnMgYXJlIHRoZSBncm91cC1sZXZlbCBzY2FsZSBwYXJhbWV0ZXJzLCB3aGljaCBjb25zdHJhaW4gdGhlIHNwcmVhZCBvZiBlZmZlY3RzIGZvciBlYWNoIHJlc3BvbnNlLCBhbmQgJFxjaGkkIGNvbXByaXNlcyB0aGUgZ3JvdXAtbGV2ZWwgcmVzaWR1YWwgY29ycmVsYXRpb24gbWF0cml4Og0KDQokJFxjaGkgPSBcYmVnaW57cG1hdHJpeH0gMSAmIFx2YXJyaG8gXFwgXHZhcnJobyAmIDEgXGVuZHtwbWF0cml4fSQkDQoNCndoZXJlaW4gJFx2YXJyaG8kIGlzIHRoZSBncm91cC1sZXZlbCByZXNpZHVhbCBjb3JyZWxhdGlvbiBiZXR3ZWVuIHJlc3BvbnNlcy4NCg0KVGhlIGV4cGxpY2l0IGluZGV4aW5nIGluIHRoZSBub3RhdGlvbiBhYm92ZSBjb252ZXlzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgcGFyYW1ldGVycyBhbmQgZWFjaCBvYnNlcnZhdGlvbiwgJGkkLCBhbmQgZW1waGFzaXplcyB0aGUgbmVzdGVkIHN0cnVjdHVyZSBvZiB0aGUgb2JzZXJ2YXRpb25zIHdpdGhpbiB0aGUgZ3JvdXAgZWZmZWN0cy4gU3BlY2lmaWNhbGx5LCBldmVyeSBvYnNlcnZhdGlvbiwgJGkkLCB3YXMgbmVzdGVkIGluIGEgbGFrZSBzaXplIGNhdGVnb3J5LCAkbCQsIHdoaWNoIHdhcyBuZXN0ZWQgaW4gYSBzdGF0ZSwgJGskLCBhbmQgZWNvcmVnaW9uLCAkaiQuIFRoZSBwYXJhbWV0ZXIgJFxhbHBoYV8xJCwgdGhlcmVmb3JlLCBhY2NvdW50ZWQgZm9yIGVjb3JlZ2lvbi1zY2FsZSBncm91cCBlZmZlY3RzIG9yIGRldmlhdGlvbnMgZnJvbSB0aGUgZ2xvYmFsIG1lYW47ICRcYWxwaGFfMiQgYWNjb3VudGVkIGZvciBzdGF0ZS1sZXZlbCBncm91cCBlZmZlY3RzIG5lc3RlZCBpbiBlY29yZWdpb25zOyBhbmQgJFxhbHBoYV8zJCBhY2NvdW50ZWQgZm9yIGxha2Ugc2l6ZSBncm91cCBlZmZlY3RzIHdpdGhpbiBzdGF0ZXMgYW5kIGVjb3JlZ2lvbnMuICANCg0KRmluYWxseSwgdGhlIG9ic2VydmF0aW9uLWxldmVsIGNvdmFyaWFuY2UgdGVybSwgJFxTaWdtYSQsIHdhcyBwYXJhbWV0ZXJpemVkIGFzOg0KJCRcU2lnbWEgPSBcYmVnaW57cG1hdHJpeH0gMSAmIFxzaWdtYV97cD0xfSBcXCBcc2lnbWFfe3A9Mn0gJiAxIFxlbmR7cG1hdHJpeH0gXE9tZWdhIFxiZWdpbntwbWF0cml4fSAxICYgXHNpZ21hX3twPTF9IFxcIFxzaWdtYV97cD0yfSAmIDEgXGVuZHtwbWF0cml4fSQkDQoNCndoZXJlaW4gdGhlICRcc2lnbWEkIHBhcmFtZXRlcnMgYXJlIHRoZSBvYnNlcnZhdGlvbi1sZXZlbCBzdGFuZGFyZCBkZXZpYXRpb25zIGZvciBlYWNoIHJlc3BvbnNlIGFuZCAkXE9tZWdhJCBjb21wcmlzZXMgdGhlIG9ic2VydmF0aW9uLWxldmVsIHJlc2lkdWFsIGNvcnJlbGF0aW9uIG1hdHJpeDoNCiQkXE9tZWdhID0gXGJlZ2lue3BtYXRyaXh9IDEgJiBccmhvIFxcIFxyaG8gJiAxIFxlbmR7cG1hdHJpeH0kJA0Kd2hlcmVpbiAkXHJobyQgaXMgdGhlIHJlc2lkdWFsIGNvcnJlbGF0aW9uIGJldHdlZW4gcmVzcG9uc2VzLg0KDQpGb3IgbW9kZWwgZml0dGluZywgcHJpb3JzIHdlcmUgbmVlZGVkIGZvciBhbGwgcGFyYW1ldGVycyBjb25kaXRpb25lZCBkaXJlY3RseSBvbiB0aGUgZGF0YSwgd2hpY2ggaW5jbHVkZWQgdGhlIGdsb2JhbCBpbnRlcmNlcHQsIHRoZSBzY2FsZSBwYXJhbWV0ZXJzLCBhbmQgdGhlIGNvcnJlbGF0aW9uIG1hdHJpY2VzLiBBIG5vcm1hbCBvciBHYXVzc2lhbiBwcmlvciwgJE4oXG11ID0gMiwgXHNpZ21hID0gMSkkIGNlbnRlcmVkIG5lYXIgdGhlIChsb2ctc2NhbGUpIGRhdGEgbWVhbnMsIHdhcyB1c2VkIGZvciB0aGUgZ2xvYmFsIGludGVyY2VwdCBwYXJhbWV0ZXIgZm9yIGVhY2ggcmVzcG9uc2UuIFRoaXMgcHJpb3Igd2FzIGNvbnNpZGVyZWQgbWluaW1hbGx5IGluZm9ybWF0aXZlIGFzIGl0IHBsYWNlZCBtb3N0ICh+ODAlKSBvZiB0aGUgcHJpb3IgbWFzcyBvdmVyIHZhbHVlcyBiZXR3ZWVuIGFwcHJveGltYXRlbHkgMiBhbmQgMjcgbmcvTCBmb3IgbWVkaWFuIE4yTyBvciBOMk8gZXF1aWxpYnJpdW0gY29uY2VudHJhdGlvbiBhbmQgaW5jbHVkZWQgc3VwcG9ydCBpbiB0aGUgdGFpbHMgZm9yIHZhbHVlcyBhcHByb2FjaGluZyAwIG5nL0wgb24gdGhlIGxvd2VyIGVuZCBhbmQgODAgbmcvTCBvbiB0aGUgaGlnaCBlbmQuIFdlIHBsYWNlZCAkRXhwKDIpJCBwcmlvcnMgb3ZlciBhbGwgc2NhbGUgcGFyYW1ldGVycywgd2hpY2ggcGxhY2VkIG1vc3Qgb2YgdGhlIHN1cHBvcnQgYmV0d2VlbiB2YWx1ZXMgdmVyeSBjbG9zZSB0byAwIGFuZCB2YWx1ZXMgbmVhciAxIChjZW50cmFsIDgwJSBkZW5zaXR5IGludGVydmFsIGZyb20gYXBwcm94aW1hdGVseSAwLjAwNSB0byAxLjE1KS4gRmluYWxseSwgZm9yIHRoZSBjb3JyZWxhdGlvbiBtYXRyaWNlcywgYW4gJExLSihcZXRhID0yKSQgcHJpb3Igd2FzIHVzZWQsIHdoaWNoLCBmb3IgYSAyLWRpbWVuc2lvbmFsIHJlc3BvbnNlLCBwbGFjZWQgbW9zdCBzdXBwb3J0IGZvciBjb3JyZWxhdGlvbnMgYmV0d2VlbiBhcHByb3hpbWF0ZWx5IC0wLjkgYW5kIDAuOS4gVGhpcyBwcmlvciBzZWVtZWQgcmVhc29uYWJsZSBhcyB0aGVyZSB3YXMgbm8gY2xlYXIgY2F1c2FsIG1lY2hhbmlzbXMgdGhhdCB3ZXJlIHRob3VnaHQgdG8gZW5zdXJlIGEgc3Ryb25nIGRpcmVjdCBjb3JyZWxhdGlvbiBiZXR3ZWVuIHRoZSBOMk8gbWVhc3VyZXMuIEFueSBwb3RlbnRpYWwgcmVzaWR1YWwgZGVwZW5kZW5jZSB3YXMgZXhwZWN0ZWQgdG8gYmUgaW5kaXJlY3QgZHVlIHRvLCBmb3IgZXhhbXBsZSwgYSBjb21tb24gY2F1c2FsIGZhY3RvciAoZS5nLiwgZWxldmF0aW9uLCB0ZW1wZXJhdHVyZSkuIEZvciBtb3JlIGluZm9ybWF0aW9uIG9uIHByaW9yIGNob2ljZSByZWNvbW1lbmRhdGlvbnMgaW4gU3Rhbiwgc2VlOiBodHRwczovL2dpdGh1Yi5jb20vc3Rhbi1kZXYvc3Rhbi93aWtpL1ByaW9yLUNob2ljZS1SZWNvbW1lbmRhdGlvbnMNCg0KVGhlICRcdGV4dGJme2JybXN9JCBwYWNrYWdlIFtAQnVya25lcl8yMDE3XSBmb3IgJFx0ZXh0YmZ7Un0kIFtAUl9Db3JlX1RlYW1fMjAyMV0gd2FzIHVzZWQgdG8gZml0IGFsbCBvZiB0aGUgbW9kZWxzIGluIGEgZnVsbHkgQmF5ZXNpYW4gc2V0dGluZy4gVGhlIGZvcm11bGEgc3ludGF4IG9mIHRoZSAkXHRleHRiZnticm1zfSQgcGFja2FnZSBpcyBzaW1pbGFyIHRvIHRoZSBzeW50YXggdXNlZCBpbiB0aGUgJFx0ZXh0YmZ7bG1lNH0kIHBhY2thZ2UgdGhhdCBpcyB3aWRlbHkgdXNlZCB0byBmaXQgbWl4ZWQgZWZmZWN0cyBtb2RlbHMgaW4gZnJlcXVlbnRpc3Qgc2V0dGluZ3MgSW4gZWl0aGVyIHBhY2thZ2UsIHRoZSBsaW5lYXIgcHJlZGljdG9yIGZvciAkXG11JCBkZXNjcmliZWQgYWJvdmUgY291bGQgYmUgZXhwcmVzc2VkIGFzOg0KDQokJFxzaW0gMSArICgxfFdTQTkpICsgKDF8V1NBOTpzdGF0ZSkgKyAoMXxXU0E5OnN0YXRlOnNpemUpJCQNCg0KSW4gdGhlICRcdGV4dGJme2JybXN9JCBwYWNrYWdlLCB0aGVyZSBpcyBhZGRpdGlvbmFseSBmdW5jdGlvbmFsaXR5IGFuZCBzeW50YXggZm9yIG11bHRpdmFyaWF0ZSByZXNwb25zZXMgYW5kIGZvciBhbGxvd2luZyB0aGUgdmFyeWluZyBpbnRlcmNlcHRzIGluIGEgbXVsdGl2YXJpYXRlIG1vZGVsIHRvIGJlIGNvcnJlbGF0ZWQsIGUuZy4sOg0KDQokJCBOXzJPX3tkaXNzb2x2ZWR9XHNpbSAxICsgKDF8YXxXU0E5KSArICgxfGJ8V1NBOTpzdGF0ZSkgKyAoMXxjfFdTQTk6c3RhdGU6c2l6ZSkgXFwgDQpOXzJPX3tlcXVpbGlicml1bX1cc2ltIDEgKyAoMXxhfFdTQTkpICsgKDF8YnxXU0E5OnN0YXRlKSArICgxfGN8V1NBOTpzdGF0ZTpzaXplKSQkDQoNClRoZSBhYm92ZSBzeW50YXggd291bGQgaW5kaWNhdGUgdGhhdCB0aGUgbGluZWFyIHByZWRpY3RvciBmb3IgYm90aCByZXNwb25zZXMgaW4gdGhlIG11bHRpdmFyaWF0ZSBtb2RlbCBoYXZlIHRoZSBzYW1lIGdyb3VwLWxldmVsIHZhcnlpbmcgZWZmZWN0cywgYW5kIHRoYXQgZWFjaCBvZiB0aG9zZSBlZmZlY3RzIGFyZSBhbGxvd2VkIHRvIGJlIGNvcnJlbGF0ZWQgYmV0d2VlbiByZXNwb25zZXMuIA0KDQpGb3IgdGhlIHJlbWFpbmRlciBvZiB0aGlzIGRvY3VtZW50LCBvbmx5IHRoaXMgc2ltcGxpZmllZCBzeW50YXggaXMgcHJlc2VudGVkIHRvIGRlc2NyaWJlIHRoZSBtb2RlbCBwYXJhbWV0ZXJpemF0aW9ucy4gRm9yIG1vcmUgaW5mb3JtYXRpb24gb24gJFx0ZXh0YmZ7YnJtc30kIGZ1bmN0aW9uYWxpdHkgYW5kIHN5bnRheCB3aXRoIG11bHRpdmFyaWF0ZSByZXNwb25zZSBtb2RlbHMsIHRoZSBwYWNrYWdlIHZpZ25ldHRlIG1heSBiZSBoZWxwZnVsLCBhbmQgY2FuIGJlIGZvdW5kIGF0OiBodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvYnJtcy92aWduZXR0ZXMvYnJtc19tdWx0aXZhcmlhdGUuaHRtbC4NCg0KIyMgTW9kZWwgMQ0KVGhlIGZpcnN0IG1vZGVsIGZpdCB3YXMgdGhlIG9uZSBkZXNjcmliZWQgYWJvdmUuDQpgYGB7ciBuMm9fbW9kX212XzEsIGV2YWw9RkFMU0UsIGluY2x1ZGU9VFJVRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2RmX21vZGVsLnJkYSIpDQoNCmJmX24ybyA8LSBiZihsb2cobjJvKSB+IDEgKyANCiAgICAgICAgICAgICAgICgxIHwgYSB8IFdTQTkpICsgDQogICAgICAgICAgICAgICAoMSB8IGIgfCBXU0E5OnN0YXRlKSArIA0KICAgICAgICAgICAgICAgKDEgfCBjIHwgV1NBOTpzdGF0ZTpzaXplX2NhdCksDQogICAgICAgICAgICAgZmFtaWx5ID0gZ2F1c3NpYW4oKSkNCg0KYmZfbjJvZXEgPC0gYmYobG9nKG4yb19lcSkgfiAxICsgDQogICAgICAgICAgICAgICAoMSB8IGEgfCBXU0E5KSArIA0KICAgICAgICAgICAgICAgKDEgfCBiIHwgV1NBOTpzdGF0ZSkgKw0KICAgICAgICAgICAgICAgKDEgfCBjIHwgV1NBOTpzdGF0ZTpzaXplX2NhdCksDQogICAgICAgICAgICAgZmFtaWx5ID0gZ2F1c3NpYW4oKSkNCg0KcHJpb3JzIDwtIGMoDQogIHByaW9yKG5vcm1hbCgyLCAxKSwgY2xhc3MgPSAiSW50ZXJjZXB0IiwgcmVzcCA9ICJsb2duMm8iKSwgIyBjZW50ZXJlZCBuZWFyIGRhdGEgbWVhbg0KICBwcmlvcihleHBvbmVudGlhbCgyKSwgY2xhc3MgPSAic2QiLCByZXNwID0gImxvZ24ybyIpLA0KICBwcmlvcihleHBvbmVudGlhbCgyKSwgY2xhc3MgPSAic2lnbWEiLCByZXNwID0gImxvZ24ybyIpLA0KICBwcmlvcihub3JtYWwoMiwgMSksIGNsYXNzID0gIkludGVyY2VwdCIsIHJlc3AgPSAibG9nbjJvZXEiKSwgIyBjZW50ZXJlZCBuZWFyIGRhdGEgbWVhbg0KICBwcmlvcihleHBvbmVudGlhbCgyKSwgY2xhc3MgPSAic2QiLCByZXNwID0gImxvZ24yb2VxIiksDQogIHByaW9yKGV4cG9uZW50aWFsKDIpLCBjbGFzcyA9ICJzaWdtYSIsIHJlc3AgPSAibG9nbjJvZXEiKSwNCiAgcHJpb3IobGtqKDIpLCBjbGFzcyA9ICJyZXNjb3IiKSwNCiAgcHJpb3IobGtqKDIpLCBjbGFzcyA9ICJjb3IiKQ0KICApDQoNCm4yb19tb2QxIDwtIGJybShiZl9uMm8gKyBiZl9uMm9lcSArIHNldF9yZXNjb3IocmVzY29yID0gVFJVRSksDQogICAgICAgICAgICAgICAgZGF0YSA9IGRmX21vZGVsLA0KICAgICAgICAgICAgICAgIHByaW9yID0gcHJpb3JzLA0KICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBsaXN0KGFkYXB0X2RlbHRhID0gMC45OSwgbWF4X3RyZWVkZXB0aCA9IDE0KSwNCiAgICAgICAgICAgICAgICAjc2FtcGxlX3ByaW9yID0gIm9ubHkiLA0KICAgICAgICAgICAgICAgIHNhdmVfcGFycyA9IHNhdmVfcGFycyhhbGwgPSBUUlVFKSwNCiAgICAgICAgICAgICAgICBzZWVkID0gMTQ1LA0KICAgICAgICAgICAgICAgIGNoYWlucz00LCANCiAgICAgICAgICAgICAgICBpdGVyPTUwMDAsIA0KICAgICAgICAgICAgICAgIGNvcmVzPTQpDQoNCnNhdmUobjJvX21vZDEsIGZpbGUgPSAiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDEucmRhIikNCmBgYA0KDQoNCiMjIyBTdW1tYXJpemUgZml0DQpUaGUgc3VtbWFyaWVzIG9mIHRoZSBlc3RpbWF0ZWQgcGFyYW1ldGVycyBhbmQga2V5IEhNQyBjb252ZXJnZW5jZSBkaWFnbm9zdGljcyBmb3IgdGhlIGZpdHRlZCBtb2RlbCBhcmUgcHJpbnRlZCBiZWxvdy4gVGhlcmUgd2VyZSBubyBvYnZpb3VzIGlzc3VlcyB3aXRoIHRoZSBITUMgc2FtcGxpbmcuIEFsbCAkXGhhdHtSfSQgdmFsdWVzIHdlcmUgbGVzcyB0aGFuIDEuMDEgYW5kIGVmZmVjdGl2ZSBzYW1wbGUgc2l6ZSAoJEVTUyQpIGNhbGN1bGF0aW9ucyBzdWdnZXN0ZWQgdGhhdCB0aGUgcG9zdGVyaW9yIGNvbnRhaW5lZCBhIHN1ZmZpY2llbnQgbnVtYmVyIG9mIGVmZmVjdGl2ZSBzYW1wbGVzIGZvciBjb25kdWN0aW5nIGluZmVyZW5jZS4NCmBgYHtyIHByaW50X21vZDEsIGVjaG89RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kMS5yZGEiKQ0KDQpwcmludChuMm9fbW9kMSwgcHJpb3IgPSBUKQ0KYGBgDQpJbiB0aGUgc3VtbWFyeSBhYm92ZSwgdGhlIGVzdGltYXRlZCBzdGFuZGFyZCBkZXZpYXRpb25zIGZvciB0aGUgdmFyeWluZyBncm91cCBlZmZlY3RzIG9uIHRoZSBtZWFuIGJlaGF2aW9yIG9mIHRoZSBkaXNzb2x2ZWQgTjJPIHJlc3BvbnNlIHN1Z2dlc3RlZCBmYWlybHkgbG93LCBidXQgbm9uLXplcm8gdmFyaWFiaWxpdHkgYWNyb3NzIGVhY2ggb2YgdGhlIHRocmVlIGxldmVscy4gVGhlIHN0YW5kYXJkIGRldmlhdGlvbnMgZXN0aW1hdGVkIGZvciB0aGUgc2FtZSB2YXJ5aW5nIGVmZmVjdHMgZm9yIGVxdWlsaWJyaXVtIE4yTyB3ZXJlIGFsc28gcmVsYXRpdmVseSBzbWFsbC4gRmluYWxseSwgbm90ZSB0aGUgcmVsYXRpdmVseSBzbWFsbCwgYnV0IHBvc2l0aXZlIHJlc2lkdWFsIGNvcnJlbGF0aW9uIGJldHdlZW4gdGhlIHR3byBOMk8gcmVzcG9uc2VzLiANCg0KQmVmb3JlIGludmVzdGluZyB0b28gbXVjaCBpbnRvIHRoZSBpbnRlcnByZXRhdGlvbiBvZiB0aGlzIG1vZGVsLCBob3dldmVyLCB0aGUgbW9kZWwgZml0IHdhcyBldmFsdWF0ZWQgYmVsb3cgdXNpbmcgYSBzZXJpZXMgb2YgZ3JhcGhpY2FsIHBvc3RlcmlvciBwcmVkaWN0aXZlIGNoZWNrcyBbUFBDOyBAR2VsbWFuX2V0YWxfMjAxNDsgQEdlbG1hbl9ldGFsXzIwMjAsIENoLiAxMV0uDQoNCiMjIyBNb2RlbCBjaGVja3MNCiMjIyMgRGlzc29sdmVkIE4yTw0KQmVsb3cgYXJlIGEgc2VyaWVzIG9mIHBhbmVscyBpbGx1c3RyYXRpbmcgZ3JhcGhpY2FsIFBQQ3MgZm9yIHRoZSBsb2coTjJPKSBjb21wb25lbnQgb2YgdGhlIG1vZGVsLiBUaGUgdG9wIGxlZnQgcGFuZWwgY29tcGFyZXMgYSBkZW5zaXR5IHBsb3Qgb2YgdGhlIG9ic2VydmVkIGRhdGEgKGJsYWNrIGxpbmUpIHRvIGRlbnNpdHkgbGluZXMgZHJhd24gZm9yIDIwMCBzYW1wbGVzIGZyb20gdGhlIHBvc3RlcmlvciBwcmVkaWN0aXZlIGRpc3RyaWJ1dGlvbiAoUFBEOyBibHVlIGxpbmVzKSBvZiB0aGUgZml0dGVkIG1vZGVsLiBUaGUgdG9wIHJpZ2h0IHBhbmVsIHNpbWlsYXJseSBjb21wYXJlcyB0aGUgY3VtdWxhdGl2ZSBkZW5zaXR5IGRpc3RyaWJ1dGlvbnMuIFRoZSBsZWZ0IG1pZGRsZSBwYW5lbCBzaW11bGF0YW5lb3VzbHkgY29tcGFyZXMgbWVhbnMgX3ZzLl8gc3RhbmRhcmQgZGV2aWF0aW9ucyBmb3IgMTAwMCBkcmF3cyBmcm9tIHRoZSBQUEQgKGJsdWUgZG90cykgdG8gdGhlIHNhbXBsZSBtZWFuIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24gKGJsYWNrIGRvdCkuIFRoZSByaWdodCBtaWRkbGUgcGFuZWwgY29tcGFyZXMgc2tld25lc3MgX3ZzLl8ga3VydG9zaXMgZm9yIDEwMDAgZHJhd3MgZnJvbSB0aGUgUFBEIHRvIHRoZSBza2V3bmVzcyBhbmQga3VydG9zaXMgdmFsdWVzIGNhbGN1bGF0ZWQgZm9yIHRoZSBvYnNlcnZlZCBkYXRhLiBUaGUgYm90dG9tIGxlZnQgcGFuZWwgY29tcGFyZXMgbWF4IF92cy5fIG1pbiB2YWx1ZXMgZm9yIDEwMDAgZHJhd3MgZnJvbSB0aGUgUFBEIHRvIHRoZSBtYXggYW5kIG1pbiB2YWx1ZXMgb2YgdGhlIHNhbXBsZSBkYXRhLiBGaW5hbGx5LCB0aGUgYm90dG9tIHJpZ2h0IHBhbmVsIHNob3dzIHRoZSBvYnNlcnZlZCBfdnMuXyBhdmVyYWdlIHByZWRpY3RlZCB2YWx1ZXMgZm9yIGVhY2ggb2JzZXJ2YXRpb24gaW4gdGhlIHNhbXBsZS4gVGhlIGF2ZXJhZ2UgcHJlZGljdGVkIHZhbHVlcyB3ZXJlIGNhbGN1bGF0ZWQgYXMgdGhlIG1lYW4gcHJlZGljdGlvbiBmb3IgZWFjaCBvYnNlcnZhdGlvbiBpbiB0aGUgUFBEIGJhc2VkIG9uIDEwMDAgZHJhd3MuDQpgYGB7ciBwcGNfbjJvMSwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD04LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDEucmRhIikNCmdyaWQuYXJyYW5nZSgNCnBwX2NoZWNrKG4yb19tb2QxLCANCiAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgIHR5cGUgPSAiZGVuc19vdmVybGF5IiwNCiAgICAgICAgIG5kcmF3cyA9IDIwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkgKw0KICB4bGFiKGV4cHJlc3Npb24ocGFzdGUoImxvZyhOIlsyXSwiTykgY29uY2VudHJhdGlvbiIpKSkgKyANCiAgeWxhYigiZGVuc2l0eSIpDQosDQpwcF9jaGVjayhuMm9fbW9kMSwgDQogICAgICAgICByZXNwID0gImxvZ24ybyIsDQogICAgICAgICB0eXBlID0gImVjZGZfb3ZlcmxheSIsDQogICAgICAgICBuZHJhd3MgPSAyMDAsIA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKSArDQogIHhsYWIoZXhwcmVzc2lvbihwYXN0ZSgibG9nKE4iWzJdLCJPKSBjb25jZW50cmF0aW9uIikpKSArIA0KICB5bGFiKCJjdW11bGF0aXZlIGRlbnNpdHkiKQ0KLA0KcHBfY2hlY2sobjJvX21vZDEsIA0KICAgICAgICAgcmVzcCA9ICJsb2duMm8iLA0KICAgICAgICAgdHlwZSA9ICJzdGF0XzJkIiwgDQogICAgICAgICBzdGF0ID0gYygibWVhbiIsICJzZCIpLA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2QxLCANCiAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoImt1cnRvc2lzIiwgInNrZXduZXNzIiksIA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2QxLCANCiAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoIm1pbiIsICJtYXgiKSwgDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KcHBfY2hlY2sobjJvX21vZDEsIA0KICAgICAgICAgcmVzcCA9ICJsb2duMm8iLA0KICAgICAgICAgdHlwZSA9ICJzY2F0dGVyX2F2ZyIsDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLCBuY29sID0gMikNCmBgYA0KVGhlIGdlbmVyYWwgdGFrZWF3YXkgZnJvbSB0aGUgUFBDcyBhYm92ZSB3YXMgdGhhdCB0aGUgbW9kZWwgcmVwbGljYXRlZCB0aGUgY2VudHJhbCB0ZW5kZW5jeSBvZiB0aGUgb2JzZXJ2ZWQgZGF0YSBmYWlybHkgd2VsbCwgYnV0IGZhaWxlZCB0byBzdWZmaWNpZW50bHkgcmVwbGljYXRlIG90aGVyIGltcG9ydGFudCBhc3BlY3RzIG9mIHRoZSBkaXN0cmlidXRpb24sIHN1Y2ggYXMgc2tld25lc3MgYW5kIGt1cnRvc2lzLiBUaGUgb2JzZXJ2ZWQgX3ZzLl8gYXZlcmFnZSBwcmVkaWN0aW9ucyBzY2F0dGVycGxvdCBzdWdnZXN0ZWQgc3Vic3RhbnRpYWwgaGV0ZXJvc2NlZGFzdGljaXR5IGluIHRoZSBlcnJvcnMuIA0KDQpUaGUgc2FtZSBjaGVja3Mgd2VyZSBydW4gYmVsb3csIGJ1dCBmb3IgdGhlIHRlc3Qgc2V0IG9mIDk1IGhlbGQtb3V0LCBzZWNvbmQtdmlzaXQgZGF0YSBwb2ludHMuIA0KYGBge3IgcHBjX24ybzFfdGVzdCwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD04LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDEucmRhIikNCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2RmX3Rlc3QucmRhIikNCmdyaWQuYXJyYW5nZSgNCnBwX2NoZWNrKG4yb19tb2QxLCANCiAgICAgICAgIG5ld2RhdGEgPSBkZl90ZXN0LA0KICAgICAgICAgcmVzcCA9ICJsb2duMm8iLA0KICAgICAgICAgdHlwZSA9ICJkZW5zX292ZXJsYXkiLA0KICAgICAgICAgbmRyYXdzID0gMjAwLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKSArDQogIHhsYWIoZXhwcmVzc2lvbihwYXN0ZSgibG9nKE4iWzJdLCJPKSBjb25jZW50cmF0aW9uIikpKSArIA0KICB5bGFiKCJkZW5zaXR5IikNCiwNCnBwX2NoZWNrKG4yb19tb2QxLCANCiAgICAgICAgIG5ld2RhdGEgPSBkZl90ZXN0LA0KICAgICAgICAgcmVzcCA9ICJsb2duMm8iLA0KICAgICAgICAgdHlwZSA9ICJlY2RmX292ZXJsYXkiLA0KICAgICAgICAgbmRyYXdzID0gMjAwLCANCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkgKw0KICB4bGFiKGV4cHJlc3Npb24ocGFzdGUoImxvZyhOIlsyXSwiTykgY29uY2VudHJhdGlvbiIpKSkgKyANCiAgeWxhYigiY3VtdWxhdGl2ZSBkZW5zaXR5IikNCiwNCnBwX2NoZWNrKG4yb19tb2QxLCANCiAgICAgICAgIG5ld2RhdGEgPSBkZl90ZXN0LA0KICAgICAgICAgcmVzcCA9ICJsb2duMm8iLA0KICAgICAgICAgdHlwZSA9ICJzdGF0XzJkIiwgDQogICAgICAgICBzdGF0ID0gYygibWVhbiIsICJzZCIpLA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2QxLCANCiAgICAgICAgIG5ld2RhdGEgPSBkZl90ZXN0LA0KICAgICAgICAgcmVzcCA9ICJsb2duMm8iLA0KICAgICAgICAgdHlwZSA9ICJzdGF0XzJkIiwgDQogICAgICAgICBzdGF0ID0gYygia3VydG9zaXMiLCAic2tld25lc3MiKSwgDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KcHBfY2hlY2sobjJvX21vZDEsIA0KICAgICAgICAgbmV3ZGF0YSA9IGRmX3Rlc3QsDQogICAgICAgICByZXNwID0gImxvZ24ybyIsDQogICAgICAgICB0eXBlID0gInN0YXRfMmQiLCANCiAgICAgICAgIHN0YXQgPSBjKCJtaW4iLCAibWF4IiksIA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2QxLCANCiAgICAgICAgIG5ld2RhdGEgPSBkZl90ZXN0LA0KICAgICAgICAgcmVzcCA9ICJsb2duMm8iLA0KICAgICAgICAgdHlwZSA9ICJzY2F0dGVyX2F2ZyIsDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLCBuY29sID0gMikNCmBgYA0KVGhlIHBhdHRlcm5zIGluIG1pc2ZpdCBpbmRpY2F0ZWQgYWJvdmUgZm9yIHRoZSByZS12aXNpdCBkYXRhIHdlcmUgc2ltaWxhciB0byB0aGUgcGF0dGVybnMgaW5kaWNhdGVkIGluIHRoZSBQUENzIHdpdGggdGhlIHRyYWluaW5nIGRhdGEuDQoNCiMjIyMgRXF1aWxpYnJpdW0gTjJPDQpCZWxvdyBhcmUgUFBDcyBmb3IgdGhlIGVxdWlsaWJyaXVtIE4yTyBjb21wb25lbnQgb2YgdGhlIG1vZGVsLiBBcyB3aXRoIHRoZSBkaXNzb2x2ZWQgTjJPIHJlc3BvbnNlIGFib3ZlLCB0aGUgbW9kZWwgZGlkIGFuIE9LIGpvYiBhdCByZXBsaWNhdGluZyB0aGUgY2VudHJhbCB0ZW5kZW5jeSwgYnV0IHBlcmZvcm1lZCBsZXNzIHdlbGwgYXQgcmVwbGljYXRpbmcgc29tZSBpbXBvcnRhbnQgYXNwZWN0cyBvZiB0aGUgb3ZlcmFsbCBkaXN0cmlidXRpb24uIA0KYGBge3IgcHBjX24yb2VxMSwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD04LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDEucmRhIikNCmdyaWQuYXJyYW5nZSgNCnBwX2NoZWNrKG4yb19tb2QxLCANCiAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLA0KICAgICAgICAgdHlwZSA9ICJkZW5zX292ZXJsYXkiLA0KICAgICAgICAgbmRyYXdzID0gMjAwLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKSArDQogIHhsYWIoZXhwcmVzc2lvbihwYXN0ZSgibG9nKE4iWzJdLCJPKSBjb25jZW50cmF0aW9uIikpKSArIA0KICB5bGFiKCJkZW5zaXR5IikNCiwNCnBwX2NoZWNrKG4yb19tb2QxLCANCiAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLA0KICAgICAgICAgdHlwZSA9ICJlY2RmX292ZXJsYXkiLA0KICAgICAgICAgbmRyYXdzID0gMjAwLCANCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkgKw0KICB4bGFiKGV4cHJlc3Npb24ocGFzdGUoImxvZyhOIlsyXSwiTykgY29uY2VudHJhdGlvbiIpKSkgKyANCiAgeWxhYigiY3VtdWxhdGl2ZSBkZW5zaXR5IikNCiwNCnBwX2NoZWNrKG4yb19tb2QxLCANCiAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLA0KICAgICAgICAgdHlwZSA9ICJzdGF0XzJkIiwgDQogICAgICAgICBzdGF0ID0gYygibWVhbiIsICJzZCIpLA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2QxLCANCiAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLA0KICAgICAgICAgdHlwZSA9ICJzdGF0XzJkIiwgDQogICAgICAgICBzdGF0ID0gYygia3VydG9zaXMiLCAic2tld25lc3MiKSwNCiAgICAgICAgIG5kcmF3cyA9IDEwMDAsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpwcF9jaGVjayhuMm9fbW9kMSwgDQogICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoIm1pbiIsICJtYXgiKSwgDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KcHBfY2hlY2sobjJvX21vZDEsIA0KICAgICAgICAgcmVzcCA9ICJsb2duMm9lcSIsDQogICAgICAgICB0eXBlID0gInNjYXR0ZXJfYXZnIiwgDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLCBuY29sID0gMikNCmBgYA0KDQpCZWxvdyBhcmUgdGhlIHNhbWUgUFBDcyBmb3IgZXF1aWxpYnJpdW0gTjJPIGluIHRoZSByZS12aXNpdCBzaXRlcy4NCmBgYHtyIHBwY19uMm9lcTFfdGVzdCwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD04LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDEucmRhIikNCmdyaWQuYXJyYW5nZSgNCnBwX2NoZWNrKG4yb19tb2QxLA0KICAgICAgICAgbmV3ZGF0YSA9IGRmX3Rlc3QsDQogICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAiZGVuc19vdmVybGF5IiwNCiAgICAgICAgIG5kcmF3cyA9IDIwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkgKw0KICB4bGFiKGV4cHJlc3Npb24ocGFzdGUoImxvZyhOIlsyXSwiTykgY29uY2VudHJhdGlvbiIpKSkgKyANCiAgeWxhYigiZGVuc2l0eSIpDQosDQpwcF9jaGVjayhuMm9fbW9kMSwgDQogICAgICAgICBuZXdkYXRhID0gZGZfdGVzdCwNCiAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLA0KICAgICAgICAgdHlwZSA9ICJlY2RmX292ZXJsYXkiLA0KICAgICAgICAgbmRyYXdzID0gMjAwLCANCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkgKw0KICB4bGFiKGV4cHJlc3Npb24ocGFzdGUoImxvZyhOIlsyXSwiTykgY29uY2VudHJhdGlvbiIpKSkgKyANCiAgeWxhYigiY3VtdWxhdGl2ZSBkZW5zaXR5IikNCiwNCnBwX2NoZWNrKG4yb19tb2QxLCANCiAgICAgICAgIG5ld2RhdGEgPSBkZl90ZXN0LA0KICAgICAgICAgcmVzcCA9ICJsb2duMm9lcSIsDQogICAgICAgICB0eXBlID0gInN0YXRfMmQiLCANCiAgICAgICAgIHN0YXQgPSBjKCJtZWFuIiwgInNkIiksDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KcHBfY2hlY2sobjJvX21vZDEsIA0KICAgICAgICAgbmV3ZGF0YSA9IGRmX3Rlc3QsDQogICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoImt1cnRvc2lzIiwgInNrZXduZXNzIiksDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KcHBfY2hlY2sobjJvX21vZDEsIA0KICAgICAgICAgbmV3ZGF0YSA9IGRmX3Rlc3QsDQogICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoIm1pbiIsICJtYXgiKSwgDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KcHBfY2hlY2sobjJvX21vZDEsIA0KICAgICAgICAgbmV3ZGF0YSA9IGRmX3Rlc3QsDQogICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAic2NhdHRlcl9hdmciLCANCiAgICAgICAgIG5kcmF3cyA9IDEwMDAsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpDQosIG5jb2wgPSAyKQ0KYGBgDQojIyMjIEJpdmFyaWF0ZQ0KVGhlIGdyYXBoaWNhbCBjaGVjayBiZWxvdyBjb21wYXJlcyBiaXZhcmlhdGUgZGVuc2l0eSBjb250b3VycyBlc3RpbWF0ZWQgZnJvbSB0aGUgb2JzZXJ2ZWQgZGF0YSAoYmxhY2sgbGluZXMpIHRvIGRlbnNpdHkgY29udG91cnMgZXN0aW1hdGVkIGZvciBlYWNoIG9mIDIwIGRyYXdzIGZyb20gdGhlIFBQRC4gVGhlIG1vZGVsIGFwcGVhcmVkIHRvIGRvIGEgZ29vZCBqb2Igb2YgcmVwbGljYXRpbmcgdGhlIGJpdmFyaWF0ZSBtZWFuLCBidXQgd2FzIHBvb3IgYXQgcmVwcmVzZW50aW5nIHRoZSBvdmVyYWxsIGpvaW50IGRpc3RyaWJ1dGlvbi4NCmBgYHtyIHBwY19iaXYxLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTQsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kMS5yZGEiKQ0KZGZfbW9kZWwgJT4lDQogIGFkZF9wcmVkaWN0ZWRfZHJhd3MobjJvX21vZDEsIA0KICAgICAgICAgICAgICAgICAgICAgIG5kcmF3cyA9IDIwKSAlPiUNCiAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAuY2F0ZWdvcnksDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gLnByZWRpY3Rpb24pICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBsb2cobjJvKSwgeSA9IGxvZyhuMm9fZXEpKSkgKw0KICBnZW9tX2RlbnNpdHlfMmQoYWVzKHggPSBsb2duMm8sIA0KICAgICAgICAgICAgICAgICAgICAgIHkgPSBsb2duMm9lcSwgDQogICAgICAgICAgICAgICAgICAgICAgZ3JvdXAgPSAuZHJhdyksDQogICAgICAgICAgICAgICAgICBiaW5zID0gMTAsDQogICAgICAgICAgICAgICAgICBjb2xvciA9ICJsaWdodGJsdWUiLCANCiAgICAgICAgICAgICAgICAgIGFscGhhID0gMC40KSArDQogIGdlb21fZGVuc2l0eV8yZChjb2xvciA9ICJibGFjayIsIGJpbnMgPSAxMCkgKw0KICB4bGltKDEuMjUsIDIuNzUpICsNCiAgeWxpbSgxLjI1LCAyLjc1KSArDQogIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KYGBgDQoNClRoZSBzYW1lIGJpdmFyaWF0ZSBjaGVjayBpcyBzaG93biBiZWxvdyBmb3IgdGhlIHJlLXZpc2l0IGRhdGEuDQpgYGB7ciBwcGNfYml2MV90ZXN0LCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTQsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kMS5yZGEiKQ0KZGZfdGVzdCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kMSwgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gMjApICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIGdncGxvdChhZXMoeCA9IGxvZyhuMm8pLCB5ID0gbG9nKG4yb19lcSkpKSArDQogIGdlb21fZGVuc2l0eV8yZChhZXMoeCA9IGxvZ24ybywgDQogICAgICAgICAgICAgICAgICAgICAgeSA9IGxvZ24yb2VxLCANCiAgICAgICAgICAgICAgICAgICAgICBncm91cCA9IC5kcmF3KSwNCiAgICAgICAgICAgICAgICAgIGJpbnMgPSAxMCwNCiAgICAgICAgICAgICAgICAgIGNvbG9yID0gImxpZ2h0Ymx1ZSIsIA0KICAgICAgICAgICAgICAgICAgYWxwaGEgPSAwLjQpICsNCiAgZ2VvbV9kZW5zaXR5XzJkKGNvbG9yID0gImJsYWNrIiwgYmlucyA9IDEwKSArDQogIHhsaW0oMS4yNSwgMi43NSkgKw0KICB5bGltKDEuMjUsIDIuNzUpICsNCiAgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIHRoZW1lX3RpZHliYXllcygpDQpgYGANCg0KIyMjIyBTYXR1cmF0aW9uDQpUaGUgZ3JhcGhpY2FsIFBQQ3MgYmVsb3cgd2VyZSBhaW1lZCBhdCBldmFsdWF0aW5nIGhvdyB3ZWxsIHRoZSBtdWx0aXZhcmlhdGUgbW9kZWwgZGlkIGF0IHJlcHJlc2VudGluZyB0aGUgb2JzZXJ2ZWQgc2F0dXJhdGlvbiByYXRpbzogDQokJE5fMk9fe2Rpc3NvbHZlZH06Tl8yT197ZXF1aWxpYnJpdW19JCQNClRoaXMgcXVhbnRpdHkgd2FzIGVzdGltYXRlZCBhcyBhIGRlcml2ZWQgdmFyaWFibGUgYnkgc2ltcGx5IGRpdmlkaW5nIHRoZSBOMk8gUFBEIGJ5IHRoZSBlcXVpbGlicml1bSBOMk8gUFBELiBMaWtld2lzZSwgdGhlIHByb3BvcnRpb24gb2YgdW5kZXItc2F0dXJhdGVkIGxha2VzIGluIHRoZSBzYW1wbGUgd2FzIGVzdGltYXRlZCBieSBzdW1taW5nIHRoZSBudW1iZXIgb2YgbGFrZXMgZnJvbSBlYWNoIHBvc3RlcmlvciBwcmVkaWN0aXZlIGRyYXcgd2hlcmVpbiB0aGUgcmF0aW8gd2FzIDwgMSBhbmQgZGl2aWRpbmcgdGhhdCBudW1iZXIgYnkgdGhlIHRvdGFsIG51bWJlciBvZiBsYWtlcyBpbiB0aGUgc2FtcGxlLCB3aGljaCB3YXMgOTg0Lg0KT3ZlcmFsbCwgdGhlc2UgY2hlY2tzIGluZGljYXRlZCB0aGF0IHByb3Blcmx5IHJlcHJlc2VudGluZyB0aGUgdGFpbHMgb2YgdGhlIE4yTyBhbmQgTjJPLWVxIG9ic2VydmF0aW9ucyB3b3VsZCBsaWtlbHkgYmUgbmVjZXNzYXJ5IGluIG9yZGVyIHRvIGJldHRlciByZXBsaWNhdGUgdGhlIG9ic2VydmVkIHNhdHVyYXRpb24gbWV0cmljcy4gRm9yIGV4YW1wbGUsIHRoZSBtb2RlbCBkaWQgYSBwb29yIGpvYiByZXBsaWNhdGluZyB0aGUgb2JzZXJ2ZWQgcHJvcG9ydGlvbiBvZiB1bmRlci1zYXR1cmF0ZWQgbGFrZXMsIHVuZGVyZXN0aW1hdGluZyBpdCBieSBtb3JlIHRoYW4gMTAgcGVyY2VudGFnZSBwb2ludHMsIG9uIGF2ZXJhZ2UuDQpgYGB7ciBwcGNfc2F0MSwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD04LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDEucmRhIikNCmdyaWQuYXJyYW5nZSgNCmRmX21vZGVsICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2QxLCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MCkgJT4lDQogIHJlbmFtZShuMm9fb2JzID0gbjJvLA0KICAgICAgICAgbjJvZXFfb2JzID0gbjJvX2VxKSAlPiUNCiAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAuY2F0ZWdvcnksDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gLnByZWRpY3Rpb24pICU+JQ0KICBtdXRhdGUoc2F0X3JhdGlvID0gbjJvX29icyAvIG4yb2VxX29icywNCiAgICAgICAgIHNhdF9wcmVkID0gZXhwKGxvZ24ybykgLyBleHAobG9nbjJvZXEpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gc2F0X3JhdGlvKSkgKw0KICBnZW9tX2RlbnNpdHkoYWVzKHggPSBzYXRfcHJlZCwgZ3JvdXAgPSAuZHJhdyksIA0KICAgICAgICAgICAgICAgbiA9IDEwMjQsIA0KICAgICAgICAgICAgICAgYWRqdXN0ID0gMSwNCiAgICAgICAgICAgICAgIGNvbG9yID0gImxpZ2h0Ymx1ZSIpICsNCiAgZ2VvbV9kZW5zaXR5KG4gPSAxMDI0LCBhZGp1c3QgPSAyKSArDQogIHhsaW0oMCwgNSkgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KZGZfbW9kZWwgJT4lDQogIGFkZF9wcmVkaWN0ZWRfZHJhd3MobjJvX21vZDEsIA0KICAgICAgICAgICAgICAgICAgICAgIG5kcmF3cyA9IDUwMCkgJT4lDQogIHJlbmFtZShuMm9fb2JzID0gbjJvLA0KICAgICAgICAgbjJvZXFfb2JzID0gbjJvX2VxKSAlPiUNCiAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAuY2F0ZWdvcnksDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gLnByZWRpY3Rpb24pICU+JQ0KICBtdXRhdGUodXNhdF9wcmVkID0gaWZlbHNlKGxvZ24ybyA8IGxvZ24yb2VxLCAxLCAwKSkgJT4lDQogIGdyb3VwX2J5KC5kcmF3KSAlPiUNCiAgc3VtbWFyaXNlKHByb3BfcHJlZCA9IHN1bSh1c2F0X3ByZWQpIC8gOTg0KSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gcHJvcF9wcmVkKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuMDAxLCBmaWxsID0gImxpZ2h0Ymx1ZSIpICsNCiAgZ2VvbV92bGluZShkYXRhID0gZGZfbW9kZWwsIG1hcHBpbmcgPSBhZXMoeGludGVyY2VwdCA9IHN1bShuMm8gPCBuMm9fZXEpLzk4NCkpICsNCiAgeGxhYigiUHJvcG9ydGlvbiB1bmRlcnNhdHVyYXRlZCB3YXRlcmJvZGllcyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCmRmX21vZGVsICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2QxLCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MDApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgbXV0YXRlKHNhdF9yYXRpbyA9IG4yb19vYnMgLyBuMm9lcV9vYnMsDQogICAgICAgICBzYXRfcHJlZCA9IGV4cChsb2duMm8pIC8gZXhwKGxvZ24yb2VxKSkgJT4lDQogIGdyb3VwX2J5KC5kcmF3KSAlPiUNCiAgbXV0YXRlKG1lYW5feXJlcCA9IG1lYW4oc2F0X3ByZWQpLA0KICAgICAgICAgc2RfeXJlcCA9IHNkKHNhdF9wcmVkKSkgJT4lIA0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZShtZWFuX3kgPSBtZWFuKHNhdF9yYXRpbyksDQogICAgICAgICBzZF95ID0gc2Qoc2F0X3JhdGlvKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IG1lYW5feXJlcCwgeSA9IHNkX3lyZXApKSArDQogIGdlb21fcG9pbnQoY29sb3IgPSAibGlnaHRibHVlIikgKw0KICBnZW9tX3ZsaW5lKGFlcyh4aW50ZXJjZXB0ID0gbWVhbl95KSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICBnZW9tX2hsaW5lKGFlcyh5aW50ZXJjZXB0ID0gc2RfeSksIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCmRmX21vZGVsICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2QxLCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MDApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgbXV0YXRlKHNhdF9yYXRpbyA9IG4yb19vYnMgLyBuMm9lcV9vYnMsDQogICAgICAgICBzYXRfcHJlZCA9IGV4cChsb2duMm8pIC8gZXhwKGxvZ24yb2VxKSkgJT4lDQogIGdyb3VwX2J5KC5kcmF3KSAlPiUNCiAgbXV0YXRlKG1pbl95cmVwID0gbWluKHNhdF9wcmVkKSwNCiAgICAgICAgIG1heF95cmVwID0gbWF4KHNhdF9wcmVkKSkgJT4lIA0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZShtaW5feSA9IG1pbihzYXRfcmF0aW8pLA0KICAgICAgICAgbWF4X3kgPSBtYXgoc2F0X3JhdGlvKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IG1pbl95cmVwLCB5ID0gbWF4X3lyZXApKSArDQogIGdlb21fcG9pbnQoY29sb3IgPSAibGlnaHRibHVlIikgKw0KICBnZW9tX3ZsaW5lKGFlcyh4aW50ZXJjZXB0ID0gbWluX3kpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIGdlb21faGxpbmUoYWVzKHlpbnRlcmNlcHQgPSBtYXhfeSksIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCmRmX21vZGVsICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2QxLCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MDApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgbXV0YXRlKHNhdF9yYXRpbyA9IG4yb19vYnMgLyBuMm9lcV9vYnMsDQogICAgICAgICBzYXRfcHJlZCA9IGV4cChsb2duMm8pIC8gZXhwKGxvZ24yb2VxKSkgJT4lDQogIGdyb3VwX2J5KC5yb3cpICU+JQ0KICBtdXRhdGUobWVhbl95cmVwID0gbWVhbihzYXRfcHJlZCkpICU+JSANCiAgZmlsdGVyKC5kcmF3ID09IDEpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbWVhbl95cmVwLCB5ID0gc2F0X3JhdGlvKSkgKw0KICBnZW9tX3BvaW50KGNvbG9yID0gImxpZ2h0Ymx1ZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosIG5jb2wgPSAyKQ0KYGBgDQoNClRoZSB0b3AgbGVmdCBwYW5lbCwgYWJvdmUsIGlzIGEgZGVuc2l0eSBwbG90IG9mIHRoZSBvYnNlcnZlZCBzYXR1cmF0aW9uIHJhdGlvIChibGFjayBsaW5lKSBjb21wYXJlZCB0byBhbiBlc3RpbWF0ZSB1c2luZyA1MCBkcmF3cyBmcm9tIHRoZSBtb2RlbCAoYmx1ZSBsaW5lcykuIFRoZSB0b3AgcmlnaHQgcGFuZWwgc2hvd3MgdGhlIG9ic2VydmVkIHByb3BvcnRpb24gb2YgdW5kZXItc2F0dXJhdGVkIGxha2VzIGNvbXBhcmVkIHRvIGEgbW9kZWwgZXN0aW1hdGUgYmFzZWQgb24gMTAwMCBkcmF3cyBmcm9tIHRoZSBQUEQuIFRoZSBsZWZ0IG1pZGRsZSBwYW5lbCBzaG93cyB0aGUgbWVhbiBfdnMuXyBzdGFuZGFyZCBkZXZpYXRpb24gb2YgdGhlIHNhdHVyYXRpb24gcmF0aW8gZm9yIHRoZSBvYnNlcnZlZCBkYXRhIGNvbXBhcmVkIHRvIHRoZSBzYW1lIGVzdGltYXRlcyBmb3IgNTAwIHBvc3RlcmlvciBkcmF3cyBmcm9tIHRoZSBtb2RlbCdzIFBQRC4gVGhlIHJpZ2h0IG1pZGRsZSBwYW5lbCBzaG93cyB0aGUgbWF4IF92cy5fIG1pbiBmb3IgdGhlIHNhbXBsZSBjb21wYXJlZCB0byA1MDAgZHJhd3MgZnJvbSB0aGUgbW9kZWwncyBQUEQuIEZpbmFsbHksIHRoZSBib3R0b20gbGVmdCBwYW5lbCBzaG93cyB0aGUgb2JzZXJ2ZWQgX3ZzLl8gYXZlcmFnZSBwcmVkaWN0ZWQgc2F0dXJhdGlvbiByYXRpbyBmb3IgYWxsIDk4NCBsYWtlcyBzYW1wbGVkIGluIHRoZSBkYXRhc2V0Lg0KDQpUaGUgc2FtZSBQUENzIGFyZSBzaG93IGJlbG93IGZvciB0aGUgcmV2aXNpdCBkYXRhLg0KYGBge3IgcHBjX3NhdDFfdGVzdCwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD04LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDEucmRhIikNCmdyaWQuYXJyYW5nZSgNCmRmX3Rlc3QgJT4lDQogIGFkZF9wcmVkaWN0ZWRfZHJhd3MobjJvX21vZDEsIA0KICAgICAgICAgICAgICAgICAgICAgIG5kcmF3cyA9IDUwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIG11dGF0ZShzYXRfcmF0aW8gPSBuMm9fb2JzIC8gbjJvZXFfb2JzLA0KICAgICAgICAgc2F0X3ByZWQgPSBleHAobG9nbjJvKSAvIGV4cChsb2duMm9lcSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBzYXRfcmF0aW8pKSArDQogIGdlb21fZGVuc2l0eShhZXMoeCA9IHNhdF9wcmVkLCBncm91cCA9IC5kcmF3KSwgDQogICAgICAgICAgICAgICBuID0gMTAyNCwgDQogICAgICAgICAgICAgICBhZGp1c3QgPSAxLA0KICAgICAgICAgICAgICAgY29sb3IgPSAibGlnaHRibHVlIikgKw0KICBnZW9tX2RlbnNpdHkobiA9IDEwMjQsIGFkanVzdCA9IDIpICsNCiAgeGxpbSgwLCA1KSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpkZl90ZXN0ICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2QxLCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MDApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgbXV0YXRlKHVzYXRfcHJlZCA9IGlmZWxzZShsb2duMm8gPCBsb2duMm9lcSwgMSwgMCkpICU+JQ0KICBncm91cF9ieSguZHJhdykgJT4lDQogIHN1bW1hcmlzZShwcm9wX3ByZWQgPSBzdW0odXNhdF9wcmVkKSAvIDk1KSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gcHJvcF9wcmVkKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuMDAxLCBmaWxsID0gImxpZ2h0Ymx1ZSIpICsNCiAgZ2VvbV92bGluZShkYXRhID0gZGZfdGVzdCwgbWFwcGluZyA9IGFlcyh4aW50ZXJjZXB0ID0gc3VtKG4ybyA8IG4yb19lcSkvOTUpKSArDQogIHhsYWIoIlByb3BvcnRpb24gdW5kZXJzYXR1cmF0ZWQgd2F0ZXJib2RpZXMiKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpkZl90ZXN0ICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2QxLCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MDApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgbXV0YXRlKHNhdF9yYXRpbyA9IG4yb19vYnMgLyBuMm9lcV9vYnMsDQogICAgICAgICBzYXRfcHJlZCA9IGV4cChsb2duMm8pIC8gZXhwKGxvZ24yb2VxKSkgJT4lDQogIGdyb3VwX2J5KC5kcmF3KSAlPiUNCiAgbXV0YXRlKG1lYW5feXJlcCA9IG1lYW4oc2F0X3ByZWQpLA0KICAgICAgICAgc2RfeXJlcCA9IHNkKHNhdF9wcmVkKSkgJT4lIA0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZShtZWFuX3kgPSBtZWFuKHNhdF9yYXRpbyksDQogICAgICAgICBzZF95ID0gc2Qoc2F0X3JhdGlvKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IG1lYW5feXJlcCwgeSA9IHNkX3lyZXApKSArDQogIGdlb21fcG9pbnQoY29sb3IgPSAibGlnaHRibHVlIikgKw0KICBnZW9tX3ZsaW5lKGFlcyh4aW50ZXJjZXB0ID0gbWVhbl95KSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICBnZW9tX2hsaW5lKGFlcyh5aW50ZXJjZXB0ID0gc2RfeSksIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCmRmX3Rlc3QgJT4lDQogIGFkZF9wcmVkaWN0ZWRfZHJhd3MobjJvX21vZDEsIA0KICAgICAgICAgICAgICAgICAgICAgIG5kcmF3cyA9IDUwMCkgJT4lDQogIHJlbmFtZShuMm9fb2JzID0gbjJvLA0KICAgICAgICAgbjJvZXFfb2JzID0gbjJvX2VxKSAlPiUNCiAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAuY2F0ZWdvcnksDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gLnByZWRpY3Rpb24pICU+JQ0KICBtdXRhdGUoc2F0X3JhdGlvID0gbjJvX29icyAvIG4yb2VxX29icywNCiAgICAgICAgIHNhdF9wcmVkID0gZXhwKGxvZ24ybykgLyBleHAobG9nbjJvZXEpKSAlPiUNCiAgZ3JvdXBfYnkoLmRyYXcpICU+JQ0KICBtdXRhdGUobWluX3lyZXAgPSBtaW4oc2F0X3ByZWQpLA0KICAgICAgICAgbWF4X3lyZXAgPSBtYXgoc2F0X3ByZWQpKSAlPiUgDQogIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlKG1pbl95ID0gbWluKHNhdF9yYXRpbyksDQogICAgICAgICBtYXhfeSA9IG1heChzYXRfcmF0aW8pKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbWluX3lyZXAsIHkgPSBtYXhfeXJlcCkpICsNCiAgZ2VvbV9wb2ludChjb2xvciA9ICJsaWdodGJsdWUiKSArDQogIGdlb21fdmxpbmUoYWVzKHhpbnRlcmNlcHQgPSBtaW5feSksIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IG1heF95KSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KZGZfdGVzdCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kMSwgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTAwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIG11dGF0ZShzYXRfcmF0aW8gPSBuMm9fb2JzIC8gbjJvZXFfb2JzLA0KICAgICAgICAgc2F0X3ByZWQgPSBleHAobG9nbjJvKSAvIGV4cChsb2duMm9lcSkpICU+JQ0KICBncm91cF9ieSgucm93KSAlPiUNCiAgbXV0YXRlKG1lYW5feXJlcCA9IG1lYW4oc2F0X3ByZWQpKSAlPiUgDQogIGZpbHRlciguZHJhdyA9PSAxKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1lYW5feXJlcCwgeSA9IHNhdF9yYXRpbykpICsNCiAgZ2VvbV9wb2ludChjb2xvciA9ICJsaWdodGJsdWUiKSArDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLCBuY29sID0gMikNCmBgYA0KVGhlIGNoZWNrcyBhYm92ZSBpbmRpY2F0ZWQgdGhhdCB0aGUgbW9kZWwgZGlkIGEgc2ltaWxhcmx5IHVuZGVyd2hlbG1pbmcgam9iIG9mIHJlcGxpY2F0aW5nIHNvbWUga2V5IHByb3BlcnRpZXMgb2YgdGhlIHNhdHVyYXRpb24gbWV0cmljcyBjYWxjdWxhdGVkIGZyb20gdGhlIHJlLXZpc2l0IGRhdGEuDQoNCiMjIyMgUi1zcXVhcmUNCkJlbG93LCB0aGUgQmF5ZXNpYW4gJFJeMiQgdmFsdWVzIGFyZSByZXBvcnRlZCBmb3IgZWFjaCByZWFzcG9uc2UgaW4gdGhlIG1vZGVsLiANCmBgYHtyIHIyXzEsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTQsIGZpZy5oZWlnaHQ9NH0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2QxLnJkYSIpDQpyb3VuZChiYXllc19SMihuMm9fbW9kMSwgcmVzcCA9ICJsb2duMm8iLCBjb3JlcyA9IDEpLCAzKQ0Kcm91bmQoYmF5ZXNfUjIobjJvX21vZDEsIHJlc3AgPSAibG9nbjJvZXEiLCBjb3JlcyA9IDEpLCAzKQ0KYGBgDQoNClRoZSAkUl4yJCB3ZXJlIGFsc28gZXN0aW1hdGVkIGZvciB0aGUgcmUtdmlzaXQgZGF0YS4NCmBgYHtyIHIyXzFfdGVzdCwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NCwgZmlnLmhlaWdodD00fQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDEucmRhIikNCnJvdW5kKGJheWVzX1IyKG4yb19tb2QxLCByZXNwID0gImxvZ24ybyIsIG5ld2RhdGEgPSBkZl90ZXN0LCBjb3JlcyA9IDEpLCAzKQ0Kcm91bmQoYmF5ZXNfUjIobjJvX21vZDEsIHJlc3AgPSAibG9nbjJvZXEiLCBuZXdkYXRhID0gZGZfdGVzdCwgY29yZXMgPSAxKSwgMykNCmBgYA0KDQojIyBNb2RlbCAyDQpJbiBhbiBhdHRlbXB0IHRvIGJldHRlciBmaXQgdGhlIG9ic2VydmVkIGRhdGEsIHRoZSBuZXh0IG1vZGVsIGluY2x1ZGVkIGRpc3RyaWJ1dGlvbmFsIHN1Yi1tb2RlbHMgdG8gYWxsb3cgZm9yIGhldGVyb2dlbmVvdXMgdmFyaWFuY2VzIGZvciBlYWNoIHJlc3BvbnNlIGNvbmRpdGlvbmFsIG9uIHRoZSBzdXJ2ZXkgZGVzaWduIHN0cnVjdHVyZS4NCmBgYHtyIG4yb19tb2RfMiwgZXZhbD1GQUxTRSwgaW5jbHVkZT1UUlVFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvZGZfbW9kZWwucmRhIikNCg0KYmZfbjJvIDwtIGJmKGxvZyhuMm8pIH4gMSArDQogICAgICAgICAgICAgICAoMSB8IGEgfCBXU0E5KSArIA0KICAgICAgICAgICAgICAgKDEgfCBiIHwgV1NBOTpzdGF0ZSkgKyANCiAgICAgICAgICAgICAgICgxIHwgYyB8IFdTQTk6c3RhdGU6c2l6ZV9jYXQpLA0KICAgICAgICAgICAgIHNpZ21hIH4gMSArDQogICAgICAgICAgICAgICAoMSB8IFdTQTkpICsgDQogICAgICAgICAgICAgICAoMSB8IFdTQTk6c3RhdGUpICsgDQogICAgICAgICAgICAgICAoMSB8IFdTQTk6c3RhdGU6c2l6ZV9jYXQpLCANCiAgICAgICAgICAgICBmYW1pbHkgPSBnYXVzc2lhbigpKQ0KDQpiZl9uMm9lcSA8LSBiZihsb2cobjJvX2VxKSB+IDEgKw0KICAgICAgICAgICAgICAgICAoMSB8IGEgfCBXU0E5KSArIA0KICAgICAgICAgICAgICAgICAoMSB8IGIgfCBXU0E5OnN0YXRlKSArDQogICAgICAgICAgICAgICAgICgxIHwgYyB8IFdTQTk6c3RhdGU6c2l6ZV9jYXQpLA0KICAgICAgICAgICAgIHNpZ21hIH4gMSArDQogICAgICAgICAgICAgICAoMSB8IFdTQTkpICsgDQogICAgICAgICAgICAgICAoMSB8IFdTQTk6c3RhdGUpICsgDQogICAgICAgICAgICAgICAoMSB8IFdTQTk6c3RhdGU6c2l6ZV9jYXQpLA0KICAgICAgICAgICAgIGZhbWlseSA9IGdhdXNzaWFuKCkpDQoNCnByaW9ycyA8LSBjKA0KICBwcmlvcihub3JtYWwoMiwgMSksIGNsYXNzID0gIkludGVyY2VwdCIsIHJlc3AgPSAibG9nbjJvIiksDQogIHByaW9yKGV4cG9uZW50aWFsKDIpLCBjbGFzcyA9ICJzZCIsIHJlc3AgPSAibG9nbjJvIiksDQogIHByaW9yKG5vcm1hbCgtMSwgMiksIGNsYXNzID0gIkludGVyY2VwdCIsIGRwYXIgPSAic2lnbWEiLCByZXNwID0gImxvZ24ybyIpLA0KICBwcmlvcihleHBvbmVudGlhbCgyKSwgY2xhc3MgPSAic2QiLCBkcGFyID0gInNpZ21hIiwgcmVzcCA9ICJsb2duMm8iKSwNCiAgcHJpb3Iobm9ybWFsKDIsIDEpLCBjbGFzcyA9ICJJbnRlcmNlcHQiLCByZXNwID0gImxvZ24yb2VxIiksIA0KICBwcmlvcihleHBvbmVudGlhbCgyKSwgY2xhc3MgPSAic2QiLCByZXNwID0gImxvZ24yb2VxIiksDQogIHByaW9yKG5vcm1hbCgtMSwgMiksIGNsYXNzID0gIkludGVyY2VwdCIsIGRwYXIgPSAic2lnbWEiLCByZXNwID0gImxvZ24yb2VxIiksDQogIHByaW9yKGV4cG9uZW50aWFsKDIpLCBjbGFzcyA9ICJzZCIsIGRwYXIgPSAic2lnbWEiLCByZXNwID0gImxvZ24yb2VxIiksDQogIA0KICBwcmlvcihsa2ooMiksIGNsYXNzID0gInJlc2NvciIpLA0KICBwcmlvcihsa2ooMiksIGNsYXNzID0gImNvciIpDQogICkNCg0KbjJvX21vZDIgPC0gYnJtKGJmX24ybyArIGJmX24yb2VxICsgc2V0X3Jlc2NvcihyZXNjb3IgPSBUUlVFKSwNCiAgICAgICAgICAgICAgICBkYXRhID0gZGZfbW9kZWwsIA0KICAgICAgICAgICAgICAgIHByaW9yID0gcHJpb3JzLA0KICBjb250cm9sID0gbGlzdChhZGFwdF9kZWx0YSA9IDAuOTc1LCBtYXhfdHJlZWRlcHRoID0gMTIpLA0KICAjc2FtcGxlX3ByaW9yID0gIm9ubHkiLA0KICBzYXZlX3BhcnMgPSBzYXZlX3BhcnMoYWxsID0gVFJVRSksDQogIHNlZWQgPSA4NDUxMiwNCiAgY2hhaW5zPTQsIA0KICBpdGVyPTUwMDAsIA0KICBjb3Jlcz00KQ0KDQpzYXZlKG4yb19tb2QyLCBmaWxlID0gIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2QyLnJkYSIpDQpgYGANCg0KIyMjIFN1bW1hcml6ZSBmaXQNClRoZSBzdW1tYXJpZXMgb2YgdGhlIGVzdGltYXRlZCBwYXJhbWV0ZXJzIGFuZCBrZXkgSE1DIGNvbnZlcmdlbmNlIGRpYWdub3N0aWNzIGZvciB0aGUgZml0dGVkIG1vZGVsIGFyZSBwcmludGVkIGJlbG93LiANCmBgYHtyIHByaW50X21vZDIsIGVjaG89RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kMi5yZGEiKQ0KDQpwcmludChuMm9fbW9kMiwgcHJpb3IgPSBUKQ0KYGBgDQpGcm9tIHRoZSBzdW1tYXJ5IGFib3ZlLCBub3RlIHRoZSBtb2RlcmF0ZSBhbmQgcG9zaXRpdmUgcmVzaWR1YWwgY29ycmVsYXRpb24gYmV0d2VlbiB0aGUgdHdvIE4yTyByZXNwb25zZXMuIFRoZSBlc3RpbWF0ZWQgc3RhbmRhcmQgZGV2aWF0aW9ucyBmb3IgdGhlIHZhcnlpbmcgZ3JvdXAgZWZmZWN0cyBvbiB0aGUgbWVhbiBiZWhhdmlvciBvZiB0aGUgZGlzc29sdmVkIE4yTyByZXNwb25zZSBzdWdnZXN0ZWQgZmFpcmx5IGxvdywgYnV0IG5vbi16ZXJvIHZhcmlhYmlsaXR5IGFjcm9zcyBlYWNoIG9mIHRoZSB0aHJlZSBsZXZlbHMuIFRoZSBzdGFuZGFyZCBkZXZpYXRpb25zIGVzdGltYXRlZCBmb3IgdGhlIHNhbWUgdmFyeWluZyBlZmZlY3RzIGZvciBlcXVpbGlicml1bSBOMk8gd2VyZSBhbHNvIHJlbGF0aXZlbHkgc21hbGwuIEhvd2V2ZXIsIGJlZm9yZSBpbnZlc3RpbmcgdG9vIG11Y2ggaW50byB0aGUgaW50ZXJwcmV0YXRpb24gb2YgdGhlc2UgcmVzdWx0cywgdGhlIG1vZGVsIGZpdCB3YXMgZnVydGhlciBldmFsdWF0ZWQgYmVsb3cgdXNpbmcgYSBzZXJpZXMgb2YgZ3JhcGhpY2FsIHBvc3RlcmlvciBwcmVkaWN0aXZlIGNoZWNrcyAoUFBDcykuDQoNCiMjIyBNb2RlbCBjaGVja3MNCkJlbG93IHRoZSBzYW1lIFBQQ3Mgd2VyZSBwZXJmb3JtZWQgYXMgd2l0aCB0aGUgaW5pdGlhbCBtb2RlbCAoc2VlIGFib3ZlIGZvciBtb3JlIGRldGFpbHMgb24gZWFjaCBwYW5lbCkuIA0KIyMjIyMgRGlzc29sdmVkIE4yTw0KVGhvdWdoIHRoZSBjaGVja3MgYmVsb3cgc3VnZ2VzdCBzb21lIGltcHJvdmVtZW50IGluIHJlcGxpY2F0aW5nIHRoZSB0YWlscyBvZiB0aGUgb2JzZXJ2ZWQgZGF0YSwgdGhpcyBtb2RlbCBkaWQgYSBwb29yZXIgam9iIGF0IHJlcGxpY2F0aW5nIGNlbnRyYWwgdGVuZGVuY3kuDQpgYGB7ciBwcGNfbjJvMiwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD04LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDIucmRhIikNCmdyaWQuYXJyYW5nZSgNCnBwX2NoZWNrKG4yb19tb2QyLCANCiAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgIHR5cGUgPSAiZGVuc19vdmVybGF5IiwNCiAgICAgICAgIG5kcmF3cyA9IDIwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkgKw0KICB4bGltKC01LCA1KSArDQogIHhsYWIoZXhwcmVzc2lvbihwYXN0ZSgibG9nKE4iWzJdLCJPKSBjb25jZW50cmF0aW9uIikpKSArIA0KICB5bGFiKCJkZW5zaXR5IikNCiwNCnBwX2NoZWNrKG4yb19tb2QyLCANCiAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgIHR5cGUgPSAiZWNkZl9vdmVybGF5IiwNCiAgICAgICAgIG5kcmF3cyA9IDIwMCwgDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgeGxpbSgtNSwgNSkgKw0KICB4bGFiKGV4cHJlc3Npb24ocGFzdGUoImxvZyhOIlsyXSwiTykgY29uY2VudHJhdGlvbiIpKSkgKyANCiAgeWxhYigiY3VtdWxhdGl2ZSBkZW5zaXR5IikNCiwNCnBwX2NoZWNrKG4yb19tb2QyLCANCiAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoIm1lYW4iLCAic2QiKSwNCiAgICAgICAgIG5kcmF3cyA9IDEwMDAsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpwcF9jaGVjayhuMm9fbW9kMiwgDQogICAgICAgICByZXNwID0gImxvZ24ybyIsDQogICAgICAgICB0eXBlID0gInN0YXRfMmQiLCANCiAgICAgICAgIHN0YXQgPSBjKCJrdXJ0b3NpcyIsICJza2V3bmVzcyIpLCANCiAgICAgICAgIG5kcmF3cyA9IDEwMDAsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpwcF9jaGVjayhuMm9fbW9kMiwgDQogICAgICAgICByZXNwID0gImxvZ24ybyIsDQogICAgICAgICB0eXBlID0gInN0YXRfMmQiLCANCiAgICAgICAgIHN0YXQgPSBjKCJtaW4iLCAibWF4IiksIA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2QyLCANCiAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgIHR5cGUgPSAic2NhdHRlcl9hdmciLCANCiAgICAgICAgIG5kcmF3cyA9IDEwMDAsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpDQosIG5jb2wgPSAyKQ0KYGBgDQoNCiMjIyMgRXF1aWxpYnJpdW0gTjJPDQpUaGUgY2hlY2tzIGJlbG93IHN1Z2dlc3QgdGhpcyBtb2RlbCBvZmZlcmVkIG5vIGltcHJvdmVtZW50IHVwb24gdGhlIGluaXRpYWwgbW9kZWwgZm9yIGVxdWlsaWJyaXVtIE4yTy4gVGhpcyBtb2RlbCBhbHNvIGFwcGVhcmVkIHRvIGRvIGEgcG9vcmVyIGpvYiBvZiByZXBsaWNhdGluZyB0aGUgbWVhbiBhbmQgb3ZlcmFsbCBzdGFuZGFyZCBkZXZpYXRpb24gY29tcGFyZWQgdG8gdGhlIGluaXRpYWwgbW9kZWwuDQpgYGB7ciBwcGNfbjJvZXEyLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTgsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kMi5yZGEiKQ0KZ3JpZC5hcnJhbmdlKA0KcHBfY2hlY2sobjJvX21vZDIsIA0KICAgICAgICAgcmVzcCA9ICJsb2duMm9lcSIsDQogICAgICAgICB0eXBlID0gImRlbnNfb3ZlcmxheSIsDQogICAgICAgICBuZHJhd3MgPSAyMDAsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgeGxhYihleHByZXNzaW9uKHBhc3RlKCJsb2coRXF1aWxpYnJpdW0gTiJbMl0sIk8pIikpKSArIA0KICB5bGFiKCJkZW5zaXR5IikNCiwNCnBwX2NoZWNrKG4yb19tb2QyLCANCiAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLA0KICAgICAgICAgdHlwZSA9ICJlY2RmX292ZXJsYXkiLA0KICAgICAgICAgbmRyYXdzID0gMjAwLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKSArDQogIHhsYWIoZXhwcmVzc2lvbihwYXN0ZSgibG9nKEVxdWlsaWJyaXVtIE4iWzJdLCJPKSIpKSkgKyANCiAgeWxhYigiY3VtdWxhdGl2ZSBkZW5zaXR5IikNCiwNCnBwX2NoZWNrKG4yb19tb2QyLCANCiAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLA0KICAgICAgICAgdHlwZSA9ICJzdGF0XzJkIiwgDQogICAgICAgICBzdGF0ID0gYygibWVhbiIsICJzZCIpLCANCiAgICAgICAgIG5kcmF3cyA9IDEwMDAsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpwcF9jaGVjayhuMm9fbW9kMiwgDQogICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoImt1cnRvc2lzIiwgInNrZXduZXNzIiksDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KcHBfY2hlY2sobjJvX21vZDIsIA0KICAgICAgICAgcmVzcCA9ICJsb2duMm9lcSIsDQogICAgICAgICB0eXBlID0gInN0YXRfMmQiLCANCiAgICAgICAgIHN0YXQgPSBjKCJtaW4iLCAibWF4IiksIA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2QyLCANCiAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLA0KICAgICAgICAgdHlwZSA9ICJzY2F0dGVyX2F2ZyIsIA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwgbmNvbCA9IDIpDQpgYGANCg0KIyMjIyBCaXZhcmlhdGUNClRoaXMgY2hlY2sgcGVyaGFwcyBzdWdnZXN0ZWQgYW4gaW1wcm92ZW1lbnQgd2l0aCByZWdhcmQgdG8gcmVwbGljYXRpbmcgdGhlIGpvaW50IGRlbnNpdHkuIEhvd2V2ZXIsIHRoZSBwcmVkaWN0aW9ucyB3ZXJlIHN0aWxsIGNsZWFybHkgb3Zlci1kaXNwZXJzZWQgcmVsYXRpdmUgdG8gdGhlIG9ic2VydmF0aW9ucy4NCmBgYHtyIHBwY19iaXYyLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTQsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kMi5yZGEiKQ0KZGZfbW9kZWwgJT4lDQogIGFkZF9wcmVkaWN0ZWRfZHJhd3MobjJvX21vZDIsIA0KICAgICAgICAgICAgICAgICAgICAgIG5kcmF3cyA9IDIwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIGdncGxvdChhZXMoeCA9IGxvZyhuMm9fb2JzKSwgeSA9IGxvZyhuMm9lcV9vYnMpKSkgKw0KICBnZW9tX2RlbnNpdHlfMmQoYWVzKHggPSBsb2duMm8sIA0KICAgICAgICAgICAgICAgICAgICAgIHkgPSBsb2duMm9lcSwgDQogICAgICAgICAgICAgICAgICAgICAgZ3JvdXAgPSAuZHJhdyksDQogICAgICAgICAgICAgICAgICBiaW5zID0gMTAsDQogICAgICAgICAgICAgICAgICBjb2xvciA9ICJsaWdodGJsdWUiLCANCiAgICAgICAgICAgICAgICAgIGFscGhhID0gMC40KSArDQogIGdlb21fZGVuc2l0eV8yZChjb2xvciA9ICJibGFjayIsIGJpbnMgPSAxMCkgKw0KICB4bGltKDEuMjUsIDIuNzUpICsNCiAgeWxpbSgxLjI1LCAyLjc1KSArDQogIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KYGBgDQoNCiMjIyMgU2F0dXJhdGlvbg0KVGhlIFBQQ3MgZm9yIHRoZSBzYXR1cmF0aW9uIG1ldHJpY3MgYmVsb3cgaW5kaWNhdGVkIHRoYXQgaW5jbHVkaW5nIHRoZSBkaXN0cmlidXRpb25hbCBtb2RlbHMgd2FzIHBlcmhhcHMgYW4gaW1wcm92ZW1lbnQgb24gdGhlIGluaXRpYWwgbW9kZWwgaW4gc29tZSBhc3BlY3RzOyBpbiBwYXJ0aWN1bGFyLCB0aGUgYmlhcyBpbiB0aGUgcHJlZGljdGVkIHByb3BvcnRpb24gb2YgdW5kZXItc2F0dXJhdGVkIGxha2VzIHdhcyBzdWJzdGFudGlhbGx5IGRlY3JlYXNlZC4gSG93ZXZlciwgdGhlcmUgYXBwZWFyZWQgdG8gc3RpbGwgYmUgaXNzdWVzIGluIHJlcGxpY2F0aW5nIHRoZSB0YWlscyBhcyB3ZWxsIGFzIGlzc3VlcyB3aXRoIGNlbnRyYWwgdGVuZGVuY3kuDQpgYGB7ciBwcGNfc2F0MiwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD04LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDIucmRhIikNCmdyaWQuYXJyYW5nZSgNCmRmX21vZGVsICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2QyLCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MCkgJT4lDQogIHJlbmFtZShuMm9fb2JzID0gbjJvLA0KICAgICAgICAgbjJvZXFfb2JzID0gbjJvX2VxKSAlPiUNCiAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAuY2F0ZWdvcnksDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gLnByZWRpY3Rpb24pICU+JQ0KICBtdXRhdGUoc2F0X3JhdGlvID0gbjJvX29icyAvIG4yb2VxX29icywNCiAgICAgICAgIHNhdF9wcmVkID0gZXhwKGxvZ24ybykgLyBleHAobG9nbjJvZXEpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gc2F0X3JhdGlvKSkgKw0KICBnZW9tX2RlbnNpdHkoYWVzKHggPSBzYXRfcHJlZCwgZ3JvdXAgPSAuZHJhdyksIA0KICAgICAgICAgICAgICAgbiA9IDEwMjQsIA0KICAgICAgICAgICAgICAgYWRqdXN0ID0gMSwNCiAgICAgICAgICAgICAgIGNvbG9yID0gImxpZ2h0Ymx1ZSIpICsNCiAgZ2VvbV9kZW5zaXR5KG4gPSAxMDI0LCBhZGp1c3QgPSAyKSArDQogIHhsaW0oMCwgNSkgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KZGZfbW9kZWwgJT4lDQogIGFkZF9wcmVkaWN0ZWRfZHJhd3MobjJvX21vZDIsIA0KICAgICAgICAgICAgICAgICAgICAgIG5kcmF3cyA9IDUwMCkgJT4lDQogIHJlbmFtZShuMm9fb2JzID0gbjJvLA0KICAgICAgICAgbjJvZXFfb2JzID0gbjJvX2VxKSAlPiUNCiAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAuY2F0ZWdvcnksDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gLnByZWRpY3Rpb24pICU+JQ0KICBtdXRhdGUodXNhdF9wcmVkID0gaWZlbHNlKGxvZ24ybyA8IGxvZ24yb2VxLCAxLCAwKSkgJT4lDQogIGdyb3VwX2J5KC5kcmF3KSAlPiUNCiAgc3VtbWFyaXNlKHByb3BfcHJlZCA9IHN1bSh1c2F0X3ByZWQpIC8gOTg0KSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gcHJvcF9wcmVkKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuMDAxLCBmaWxsID0gImxpZ2h0Ymx1ZSIpICsNCiAgZ2VvbV92bGluZShkYXRhID0gZGZfbW9kZWwsIG1hcHBpbmcgPSBhZXMoeGludGVyY2VwdCA9IHN1bShuMm8gPCBuMm9fZXEpLzk4NCkpICsNCiAgeGxhYigiUHJvcG9ydGlvbiB1bmRlcnNhdHVyYXRlZCB3YXRlcmJvZGllcyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCmRmX21vZGVsICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2QyLCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MDApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgbXV0YXRlKHNhdF9yYXRpbyA9IG4yb19vYnMgLyBuMm9lcV9vYnMsDQogICAgICAgICBzYXRfcHJlZCA9IGV4cChsb2duMm8pIC8gZXhwKGxvZ24yb2VxKSkgJT4lDQogIGdyb3VwX2J5KC5kcmF3KSAlPiUNCiAgbXV0YXRlKG1lYW5feXJlcCA9IG1lYW4oc2F0X3ByZWQpLA0KICAgICAgICAgc2RfeXJlcCA9IHNkKHNhdF9wcmVkKSkgJT4lIA0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZShtZWFuX3kgPSBtZWFuKHNhdF9yYXRpbyksDQogICAgICAgICBzZF95ID0gc2Qoc2F0X3JhdGlvKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IG1lYW5feXJlcCwgeSA9IHNkX3lyZXApKSArDQogIGdlb21fcG9pbnQoY29sb3IgPSAibGlnaHRibHVlIikgKw0KICBnZW9tX3ZsaW5lKGFlcyh4aW50ZXJjZXB0ID0gbWVhbl95KSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICBnZW9tX2hsaW5lKGFlcyh5aW50ZXJjZXB0ID0gc2RfeSksIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCmRmX21vZGVsICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2QyLCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MDApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgbXV0YXRlKHNhdF9yYXRpbyA9IG4yb19vYnMgLyBuMm9lcV9vYnMsDQogICAgICAgICBzYXRfcHJlZCA9IGV4cChsb2duMm8pIC8gZXhwKGxvZ24yb2VxKSkgJT4lDQogIGdyb3VwX2J5KC5kcmF3KSAlPiUNCiAgbXV0YXRlKG1pbl95cmVwID0gbWluKHNhdF9wcmVkKSwNCiAgICAgICAgIG1heF95cmVwID0gbWF4KHNhdF9wcmVkKSkgJT4lIA0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZShtaW5feSA9IG1pbihzYXRfcmF0aW8pLA0KICAgICAgICAgbWF4X3kgPSBtYXgoc2F0X3JhdGlvKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IG1pbl95cmVwLCB5ID0gbWF4X3lyZXApKSArDQogIGdlb21fcG9pbnQoY29sb3IgPSAibGlnaHRibHVlIikgKw0KICBnZW9tX3ZsaW5lKGFlcyh4aW50ZXJjZXB0ID0gbWluX3kpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIGdlb21faGxpbmUoYWVzKHlpbnRlcmNlcHQgPSBtYXhfeSksIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCmRmX21vZGVsICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2QyLCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MDApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgbXV0YXRlKHNhdF9yYXRpbyA9IG4yb19vYnMgLyBuMm9lcV9vYnMsDQogICAgICAgICBzYXRfcHJlZCA9IGV4cChsb2duMm8pIC8gZXhwKGxvZ24yb2VxKSkgJT4lDQogIGdyb3VwX2J5KC5yb3cpICU+JQ0KICBtdXRhdGUobWVhbl95cmVwID0gbWVhbihzYXRfcHJlZCkpICU+JSANCiAgZmlsdGVyKC5kcmF3ID09IDEpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbWVhbl95cmVwLCB5ID0gc2F0X3JhdGlvKSkgKw0KICBnZW9tX3BvaW50KGNvbG9yID0gImxpZ2h0Ymx1ZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosIG5jb2wgPSAyKQ0KYGBgDQoNCiMjIyMgUi1zcXVhcmUNClJlbGF0aXZlIHRvIG1vZGVsIDEsIHRoZXJlIHdhcyBhIHN1YnN0YW50aWFsIGRlY3JlYXNlIGluIHRoZSAkUl4yJCBlc3RpbWF0ZSBmb3IgdGhlIGRpc3NvbHZlZCBOMk8gY29tcG9uZW50IG9mIHRoaXMgbW9kZWwuIFRoZSBlc3RpbWF0ZSBmb3IgdGhlIGVxdWlsaWJyaXVtIE4yTy1lcSBjb21wb25lbnQgd2FzIHNpbWlsYXIgdG8gdGhlIG1vZGVsIDEuIA0KYGBge3IgcjJfMiwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NCwgZmlnLmhlaWdodD00fQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDIucmRhIikNCnJvdW5kKGJheWVzX1IyKG4yb19tb2QyLCByZXNwID0gImxvZ24ybyIsIGNvcmVzID0gMSksIDMpIA0Kcm91bmQoYmF5ZXNfUjIobjJvX21vZDIsIHJlc3AgPSAibG9nbjJvZXEiLCBjb3JlcyA9IDEpLCAzKQ0KYGBgDQoNCiMjIE1vZGVsIDMNCkluIHRoZSBuZXh0IG1vZGVsLCB3ZSB1c2VkIGNvdmFyaWF0ZXMgdG8gdHJ5IHRvIGltcHJvdmUgdGhlIGZpdC4gVGhlIGNhdGVnb3JpY2FsIHZlcnNpb24gb2YgdGhlIE5PMyBjb3ZhcmlhdGUgd2FzIHVzZWQgYXMgYSBtb25vdG9uaWMgb3JkaW5hbCBwcmVkaWN0b3IgaW4gdGhlIGRpc3NvbHZlZCBOMk8gY29tcG9uZW50IG9mIHRoZSBtb2RsLiBGb3IgdGhlIGVxdWxpYnJpdW0gTjJPIGNvbXBvbmVudCwgd2UgaW5jbHVkZWQgc3VyZmFjZSB0ZW1wZXJhdHVyZSBhbmQgbG9nLXRyYW5zZm9ybWVkIGVsZXZhdGlvbiwgYWxvbmcgd2l0aCB0aGVpciBpbnRlcmFjdGlvbi4gVGhlIG1vZGVscyBhbHNvIHJldGFpbmVkIHRoZSBkaXN0cmlidXRpb25hbCBzcGVjaWZpY2F0aW9ucyBpbmNsdWRlZCBpbiBtb2RlbCAyIGFib3ZlLg0KYGBge3IgbjJvX21vZF8zLCBldmFsPUZBTFNFLCBpbmNsdWRlPVRSVUV9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZl9tb2RlbC5yZGEiKQ0KDQpiZl9uMm8gPC0gYmYobG9nKG4ybykgfiBtbyhubzNfY2F0KSArDQogICAgICAgICAgICAgICBzdXJmdGVtcCArDQogICAgICAgICAgICAgICAobW8obm8zX2NhdCkgfCBhIHwgV1NBOSkgKyANCiAgICAgICAgICAgICAgIChtbyhubzNfY2F0KSB8IGIgfCBXU0E5OnN0YXRlKSArIA0KICAgICAgICAgICAgICAgKDEgfCBjIHwgV1NBOTpzdGF0ZTpzaXplX2NhdCksDQogICAgICAgICAgICAgc2lnbWEgfiAxICsNCiAgICAgICAgICAgICAgICgxIHwgV1NBOSkgKyANCiAgICAgICAgICAgICAgICgxIHwgV1NBOTpzdGF0ZSkgKyANCiAgICAgICAgICAgICAgICgxIHwgV1NBOTpzdGF0ZTpzaXplX2NhdCksIA0KICAgICAgICAgICAgIGZhbWlseSA9IGdhdXNzaWFuKCkpDQoNCmJmX24yb2VxIDwtIGJmKGxvZyhuMm9fZXEpIH4gc3VyZnRlbXAgKw0KICAgICAgICAgICAgICAgICBsb2dfZWxldiArDQogICAgICAgICAgICAgICAgIHN1cmZ0ZW1wOmxvZ19lbGV2ICsNCiAgICAgICAgICAgICAgICAgKDEgfCBhIHwgV1NBOSkgKyANCiAgICAgICAgICAgICAgICAgKDEgfCBiIHwgV1NBOTpzdGF0ZSkgKw0KICAgICAgICAgICAgICAgICAoMSB8IGMgfCBXU0E5OnN0YXRlOnNpemVfY2F0KSwNCiAgICAgICAgICAgICBzaWdtYSB+IDEgKw0KICAgICAgICAgICAgICAgKDEgfCBXU0E5KSArIA0KICAgICAgICAgICAgICAgKDEgfCBXU0E5OnN0YXRlKSArIA0KICAgICAgICAgICAgICAgKDEgfCBXU0E5OnN0YXRlOnNpemVfY2F0KSwNCiAgICAgICAgICAgICBmYW1pbHkgPSBnYXVzc2lhbigpKQ0KDQpwcmlvcnMgPC0gYygNCiAgcHJpb3Iobm9ybWFsKDIsIDEpLCBjbGFzcyA9ICJJbnRlcmNlcHQiLCByZXNwID0gImxvZ24ybyIpLA0KICBwcmlvcihub3JtYWwoMCwgMSksIGNsYXNzID0gImIiLCByZXNwID0gImxvZ24ybyIpLA0KICBwcmlvcihleHBvbmVudGlhbCgyKSwgY2xhc3MgPSAic2QiLCByZXNwID0gImxvZ24ybyIpLA0KICBwcmlvcihub3JtYWwoLTEsIDIpLCBjbGFzcyA9ICJJbnRlcmNlcHQiLCBkcGFyID0gInNpZ21hIiwgcmVzcCA9ICJsb2duMm8iKSwNCiAgcHJpb3IoZXhwb25lbnRpYWwoMiksIGNsYXNzID0gInNkIiwgZHBhciA9ICJzaWdtYSIsIHJlc3AgPSAibG9nbjJvIiksDQogIHByaW9yKG5vcm1hbCgyLCAxKSwgY2xhc3MgPSAiSW50ZXJjZXB0IiwgcmVzcCA9ICJsb2duMm9lcSIpLCANCiAgcHJpb3Iobm9ybWFsKDAsIDEpLCBjbGFzcyA9ICJiIiwgcmVzcCA9ICJsb2duMm9lcSIpLCANCiAgcHJpb3IoZXhwb25lbnRpYWwoMiksIGNsYXNzID0gInNkIiwgcmVzcCA9ICJsb2duMm9lcSIpLCANCiAgcHJpb3Iobm9ybWFsKC0xLCAyKSwgY2xhc3MgPSAiSW50ZXJjZXB0IiwgZHBhciA9ICJzaWdtYSIsIHJlc3AgPSAibG9nbjJvZXEiKSwNCiAgcHJpb3IoZXhwb25lbnRpYWwoMiksIGNsYXNzID0gInNkIiwgZHBhciA9ICJzaWdtYSIsIHJlc3AgPSAibG9nbjJvZXEiKSwNCiAgDQogIHByaW9yKGxraigyKSwgY2xhc3MgPSAicmVzY29yIiksDQogIHByaW9yKGxraigyKSwgY2xhc3MgPSAiY29yIikNCiAgKQ0KDQpuMm9fbW9kMyA8LSBicm0oYmZfbjJvICsgYmZfbjJvZXEgKyBzZXRfcmVzY29yKHJlc2NvciA9IFRSVUUpLA0KICAgICAgICAgICAgICAgIGRhdGEgPSBkZl9tb2RlbCwgDQogICAgICAgICAgICAgICAgcHJpb3IgPSBwcmlvcnMsDQogIGNvbnRyb2wgPSBsaXN0KGFkYXB0X2RlbHRhID0gMC45NzUsIG1heF90cmVlZGVwdGggPSAxMiksDQogICNzYW1wbGVfcHJpb3IgPSAib25seSIsDQogIHNhdmVfcGFycyA9IHNhdmVfcGFycyhhbGwgPSBUUlVFKSwNCiAgc2VlZCA9IDk4NDU2LA0KICBjaGFpbnM9NCwgDQogIGl0ZXI9NTAwMCwgDQogIGNvcmVzPTQpDQoNCnNhdmUobjJvX21vZDMsIGZpbGUgPSAiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDMucmRhIikNCmBgYA0KDQojIyMgU3VtbWFyaXplIGZpdA0KVGhlIGZpdHRlZCBwYXJhbWV0ZXJzIGFuZCBNQ01DIGRpYWdub3N0aWNzIGFyZSBiZWxvdy4NCmBgYHtyIHByaW50X21vZDMsIGVjaG89RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kMy5yZGEiKQ0KDQpwcmludChuMm9fbW9kMywgcHJpb3IgPSBUKQ0KYGBgDQoNCiMjIyBNb2RlbCBjaGVja3MNCiMjIyMgRGlzc29sdmVkIE4yTw0KVGhlIFBQQ3MgYmVsb3cgaW5kaWNhdGVkIGEgYmV0dGVyIGZpdCBjb21wYXJlZCB0byB0aGUgcHJldmlvdXMgbW9kZWxzLiBUaGUgY2VudHJhbCB0ZW5kZW5jeSBhbmQgdGFpbCBiZWhhdmlvciBsb29rZWQgdG8gYmUgcmVhc29uYWJseSByZXBsaWNhdGVkIGJ5IGNvbXBhcmlzb24uIEhvd2V2ZXIsIHRoZSBvYnNlcnZlZCBfdnMuXyBwcmVkaWN0ZWQgcGxvdCBzdWdnZXN0ZWQgdGhhdCBsYXJnZXIgb3ZlcnNlcnZlZCB2YWx1ZXMgd2VyZSBiZWluZyBzeXN0ZW1hdGljYWxseSB1bmRlcmVzdGltYXRlZC4NCmBgYHtyIHBwY19mdWxsX2NoZWNrc19tb2RfbjJvMywgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD04LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDMucmRhIikNCmdyaWQuYXJyYW5nZSgNCnBwX2NoZWNrKG4yb19tb2QzLCANCiAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgIHR5cGUgPSAiZGVuc19vdmVybGF5IiwNCiAgICAgICAgIG5kcmF3cyA9IDIwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkgKw0KICB4bGltKDAsIDUpICsNCiAgeGxhYihleHByZXNzaW9uKHBhc3RlKCJsb2coTiJbMl0sIk8pIikpKSArIA0KICB5bGFiKCJkZW5zaXR5IikNCiwNCnBwX2NoZWNrKG4yb19tb2QzLCANCiAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgIHR5cGUgPSAiZWNkZl9vdmVybGF5IiwNCiAgICAgICAgIG5kcmF3cyA9IDIwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkgKw0KICB4bGltKDAsIDUpICsNCiAgeGxhYihleHByZXNzaW9uKHBhc3RlKCJsb2coTiJbMl0sIk8pIikpKSArIA0KICB5bGFiKCJjdW11bGF0aXZlIGRlbnNpdHkiKQ0KLA0KcHBfY2hlY2sobjJvX21vZDMsIA0KICAgICAgICAgcmVzcCA9ICJsb2duMm8iLA0KICAgICAgICAgdHlwZSA9ICJzdGF0XzJkIiwgDQogICAgICAgICBzdGF0ID0gYygibWVhbiIsICJzZCIpLCANCiAgICAgICAgIG5kcmF3cyA9IDEwMDAsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpwcF9jaGVjayhuMm9fbW9kMywgDQogICAgICAgICByZXNwID0gImxvZ24ybyIsDQogICAgICAgICB0eXBlID0gInN0YXRfMmQiLCANCiAgICAgICAgIHN0YXQgPSBjKCJrdXJ0b3NpcyIsICJza2V3bmVzcyIpLCAgDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KcHBfY2hlY2sobjJvX21vZDMsIA0KICAgICAgICAgcmVzcCA9ICJsb2duMm8iLA0KICAgICAgICAgdHlwZSA9ICJzdGF0XzJkIiwgDQogICAgICAgICBzdGF0ID0gYygibWluIiwgIm1heCIpLCAgDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KcHBfY2hlY2sobjJvX21vZDMsIA0KICAgICAgICAgcmVzcCA9ICJsb2duMm8iLA0KICAgICAgICAgdHlwZSA9ICJzY2F0dGVyX2F2ZyIsICANCiAgICAgICAgIG5kcmF3cyA9IDEwMDAsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpDQosIG5jb2wgPSAyKQ0KYGBgDQoNCiMjIyMgRXF1aWxpYnJpdW0gTjJPDQpUaGUgUFBDcyBiZWxvdyBpbmRpY2F0ZWQgdGhhdCB0aGlzIG1vZGVsIGFwcGVhcmVkIHRvIGJlIGFuIGltcHJvdmVtZW50IGZvciBlcXVpbGlicml1bSBOMk8gYXMgd2VsbC4gSG93ZXZlciwgc29tZSBjaGVja3MgKGUuZy4sIHNrZXduZXNzKSBzdWdnZXN0ZWQgc29tZSByb29tIGZvciBhZGRpdGlvbmFsIGltcHJvdmVtZW50Lg0KYGBge3IgcHBjX2Z1bGxfY2hlY2tzX21vZF9uMm9lcTMsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2QzLnJkYSIpDQpncmlkLmFycmFuZ2UoDQpwcF9jaGVjayhuMm9fbW9kMywgDQogICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAiZGVuc19vdmVybGF5IiwgDQogICAgICAgICBuZHJhd3MgPSAyMDAsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgeGxhYihleHByZXNzaW9uKHBhc3RlKCJsb2coRXF1aWxpYnJpdW0gTiJbMl0sIk8pIikpKSArIA0KICB5bGFiKCJkZW5zaXR5IikNCiwNCnBwX2NoZWNrKG4yb19tb2QzLCANCiAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLA0KICAgICAgICAgdHlwZSA9ICJlY2RmX292ZXJsYXkiLCANCiAgICAgICAgIG5kcmF3cyA9IDIwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkgKw0KICB4bGFiKGV4cHJlc3Npb24ocGFzdGUoImxvZyhFcXVpbGlicml1bSBOIlsyXSwiTykiKSkpICsgDQogIHlsYWIoImN1bXVsYXRpdmUgZGVuc2l0eSIpDQosDQpwcF9jaGVjayhuMm9fbW9kMywgDQogICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoIm1lYW4iLCAic2QiKSwgIA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2QzLCANCiAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLA0KICAgICAgICAgdHlwZSA9ICJzdGF0XzJkIiwgDQogICAgICAgICBzdGF0ID0gYygia3VydG9zaXMiLCAic2tld25lc3MiKSwgDQogICAgICAgICBuZHJhd3MgPSAxMDAwLCANCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2QzLCANCiAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLA0KICAgICAgICAgdHlwZSA9ICJzdGF0XzJkIiwgDQogICAgICAgICBzdGF0ID0gYygibWluIiwgIm1heCIpLCAgDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KcHBfY2hlY2sobjJvX21vZDMsIA0KICAgICAgICAgcmVzcCA9ICJsb2duMm9lcSIsDQogICAgICAgICB0eXBlID0gInNjYXR0ZXJfYXZnIiwgIA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwgbmNvbCA9IDIpDQpgYGANCg0KIyMjIyBCaXZhcmlhdGUNClRoZSBjaGVjayBmb3IgdGhlIGpvaW50IGRpc3RyaWJ1dGlvbiBiZWxvdyBhbHNvIHN1Z2dlc3RlZCBhbiBpbXByb3ZlbWVudCB1cCB0aGUgcHJldmlvdXMgbW9kZWxzLg0KYGBge3IgcHBjX2J2X2NoZWNrX21vZF9uMm8zLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTQsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kMy5yZGEiKQ0KZGZfbW9kZWwgJT4lDQogIGFkZF9wcmVkaWN0ZWRfZHJhd3MobjJvX21vZDMsIA0KICAgICAgICAgICAgICAgICAgICAgIG5kcmF3cyA9IDIwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIGdncGxvdChhZXMoeCA9IGxvZyhuMm9fb2JzKSwgeSA9IGxvZyhuMm9lcV9vYnMpKSkgKw0KICBnZW9tX2RlbnNpdHlfMmQoYWVzKHggPSBsb2duMm8sIA0KICAgICAgICAgICAgICAgICAgICAgIHkgPSBsb2duMm9lcSwgDQogICAgICAgICAgICAgICAgICAgICAgZ3JvdXAgPSAuZHJhdyksDQogICAgICAgICAgICAgICAgICBiaW5zID0gMTAsDQogICAgICAgICAgICAgICAgICBjb2xvciA9ICJsaWdodGJsdWUiLCANCiAgICAgICAgICAgICAgICAgIGFscGhhID0gMC40KSArDQogIGdlb21fZGVuc2l0eV8yZChjb2xvciA9ICJibGFjayIsIGJpbnMgPSAxMCkgKw0KICB4bGltKDEuMjUsIDIuNzUpICsNCiAgeWxpbSgxLjI1LCAyLjc1KSArDQogIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KYGBgDQoNCiMjIyMgU2F0dXJhdGlvbg0KVGhpcyBtb2RlbCBsb29rZWQgdG8gYmUgYW4gaW1wcm92ZW1lbnQgd2l0aCByZWdhcmQgdG8gdGhlIFBQQ3MgZm9yIHRoZSBzYXR1cmF0aW9uIG1ldHJpY3MuIEhvd2V2ZXIsIHRoZSBwcm9wb3J0aW9uIG9mIHVuZGVyLXNhdHVyYXRlZCBsYWtlcyByZW1haW5lZCBiaWFzZWQgbG93IGFuZCBvdGhlciBjaGVja3MgaW5kaWNhdGVkIHRoYXQgZnVydGhlciBpbXByb3ZlbWVudHMgd291bGQgYmUgaWRlYWwuDQpgYGB7ciBwcGNfc2F0X2NoZWNrX21vZF9uMm8zLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTgsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kMy5yZGEiKQ0KZ3JpZC5hcnJhbmdlKA0KZGZfbW9kZWwgJT4lDQogIGFkZF9wcmVkaWN0ZWRfZHJhd3MobjJvX21vZDMsIA0KICAgICAgICAgICAgICAgICAgICAgIG5kcmF3cyA9IDUwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIG11dGF0ZShzYXRfcmF0aW8gPSBuMm9fb2JzIC8gbjJvZXFfb2JzLA0KICAgICAgICAgc2F0X3ByZWQgPSBleHAobG9nbjJvKSAvIGV4cChsb2duMm9lcSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBzYXRfcmF0aW8pKSArDQogIGdlb21fZGVuc2l0eShhZXMoeCA9IHNhdF9wcmVkLCBncm91cCA9IC5kcmF3KSwgDQogICAgICAgICAgICAgICBuID0gMTAyNCwgDQogICAgICAgICAgICAgICBhZGp1c3QgPSAxLA0KICAgICAgICAgICAgICAgY29sb3IgPSAibGlnaHRibHVlIikgKw0KICBnZW9tX2RlbnNpdHkobiA9IDEwMjQsIGFkanVzdCA9IDIpICsNCiAgeGxpbSgwLCA1KSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpkZl9tb2RlbCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kMywgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTAwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIG11dGF0ZSh1c2F0X3ByZWQgPSBpZmVsc2UoZXhwKGxvZ24ybykgPCBleHAobG9nbjJvZXEpLCAxLCAwKSkgJT4lDQogIGdyb3VwX2J5KC5kcmF3KSAlPiUNCiAgc3VtbWFyaXNlKHByb3BfcHJlZCA9IHN1bSh1c2F0X3ByZWQpIC8gOTg0KSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gcHJvcF9wcmVkKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuMDAxLCBmaWxsID0gImxpZ2h0Ymx1ZSIpICsNCiAgZ2VvbV92bGluZShkYXRhID0gZGZfbW9kZWwsIG1hcHBpbmcgPSBhZXMoeGludGVyY2VwdCA9IHN1bShuMm8gPCBuMm9fZXEpLzk4NCkpICsNCiAgeGxhYigiUHJvcG9ydGlvbiB1bmRlcnNhdHVyYXRlZCB3YXRlcmJvZGllcyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCmRmX21vZGVsICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2QzLCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MDApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgbXV0YXRlKHNhdF9yYXRpbyA9IG4yb19vYnMgLyBuMm9lcV9vYnMsDQogICAgICAgICBzYXRfcHJlZCA9IGV4cChsb2duMm8pIC8gZXhwKGxvZ24yb2VxKSkgJT4lDQogIGdyb3VwX2J5KC5kcmF3KSAlPiUNCiAgbXV0YXRlKG1lYW5feXJlcCA9IG1lYW4oc2F0X3ByZWQpLA0KICAgICAgICAgc2RfeXJlcCA9IHNkKHNhdF9wcmVkKSkgJT4lIA0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZShtZWFuX3kgPSBtZWFuKHNhdF9yYXRpbyksDQogICAgICAgICBzZF95ID0gc2Qoc2F0X3JhdGlvKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IG1lYW5feXJlcCwgeSA9IHNkX3lyZXApKSArDQogIGdlb21fcG9pbnQoY29sb3IgPSAibGlnaHRibHVlIikgKw0KICBnZW9tX3ZsaW5lKGFlcyh4aW50ZXJjZXB0ID0gbWVhbl95KSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICBnZW9tX2hsaW5lKGFlcyh5aW50ZXJjZXB0ID0gc2RfeSksIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCmRmX21vZGVsICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2QzLCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MDApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgbXV0YXRlKHNhdF9yYXRpbyA9IG4yb19vYnMgLyBuMm9lcV9vYnMsDQogICAgICAgICBzYXRfcHJlZCA9IGV4cChsb2duMm8pIC8gZXhwKGxvZ24yb2VxKSkgJT4lDQogIGdyb3VwX2J5KC5kcmF3KSAlPiUNCiAgbXV0YXRlKG1pbl95cmVwID0gbWluKHNhdF9wcmVkKSwNCiAgICAgICAgIG1heF95cmVwID0gbWF4KHNhdF9wcmVkKSkgJT4lIA0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZShtaW5feSA9IG1pbihzYXRfcmF0aW8pLA0KICAgICAgICAgbWF4X3kgPSBtYXgoc2F0X3JhdGlvKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IG1pbl95cmVwLCB5ID0gbWF4X3lyZXApKSArDQogIGdlb21fcG9pbnQoY29sb3IgPSAibGlnaHRibHVlIikgKw0KICBnZW9tX3ZsaW5lKGFlcyh4aW50ZXJjZXB0ID0gbWluX3kpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIGdlb21faGxpbmUoYWVzKHlpbnRlcmNlcHQgPSBtYXhfeSksIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCmRmX21vZGVsICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2QzLCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MDApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgbXV0YXRlKHNhdF9yYXRpbyA9IG4yb19vYnMgLyBuMm9lcV9vYnMsDQogICAgICAgICBzYXRfcHJlZCA9IGV4cChsb2duMm8pIC8gZXhwKGxvZ24yb2VxKSkgJT4lDQogIGdyb3VwX2J5KC5yb3cpICU+JQ0KICBtdXRhdGUobWVhbl95cmVwID0gbWVhbihzYXRfcHJlZCkpICU+JSANCiAgZmlsdGVyKC5kcmF3ID09IDEpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbWVhbl95cmVwLCB5ID0gc2F0X3JhdGlvKSkgKw0KICBnZW9tX3BvaW50KGNvbG9yID0gImxpZ2h0Ymx1ZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosIG5jb2wgPSAyKQ0KYGBgDQoNCiMjIyMgUi1zcXVhcmUNClRoZSAkUl4yJCBlc3RpbWF0ZXMgZm9yIHRoaXMgbW9kZWwgYXJlIGJlbG93IGFuZCBzdWdnZXN0ZWQgc3Vic3RhbnRpYWwgaW1wcm92ZW1lbnRzIG9uIHRoZSBwcmV2aW91cyBtb2RlbHMuDQpgYGB7ciByMl9tb2RfbjJvMywgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NCwgZmlnLmhlaWdodD00fQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDMucmRhIikNCnJvdW5kKGJheWVzX1IyKG4yb19tb2QzLCByZXNwID0gImxvZ24ybyIsIGNvcmVzID0gMSksIDMpIA0Kcm91bmQoYmF5ZXNfUjIobjJvX21vZDMsIHJlc3AgPSAibG9nbjJvZXEiLCBjb3JlcyA9IDEpLCAzKQ0KYGBgDQoNCiMjIyBDb3ZhcmlhdGUgZWZmZWN0cw0KQmVsb3cgYXJlIHBsb3RzIGlsbHVzdHJhdGluZyB0aGUgbW9kZWxlZCBlZmZlY3RzIG9mIGNvdmFyaWF0ZXMgb24gYm90aCBOMk8gYW5kIGVxdWlsaWJyaXVtIE4yTy4NCiMjIyMgTjJPDQpUaGUgY29uZGl0aW9uYWwgZWZmZWN0cyBwbG90cyBiZWxvdyBmb3IgTjJPIGlsbHVzdHJhdGUgYSBwb3NpdGl2ZSwgbW9ub3RvbmljLCBhbmQgbm9uLWxpbmVhciByZWxhdGlvbnNoaXAgYmV0d2VlbiBOTzMgYW5kIE4yTzsgYW5kIGEgbmVnYXRpdmUsIGxpbmVhciByZWxhdGlvbnNoaXAgYmV0d2VlbiBzdXJmYWNlIHRlbXBlcmF0dXJlIGFuZCBOMk8uDQpgYGB7ciBjb25kaXRpb25hbF9lZmZlY3RzX21vZF9uMm8zLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTN9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kMy5yZGEiKQ0KDQpwMSA8LSBjb25kaXRpb25hbF9lZmZlY3RzKG4yb19tb2QzLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcCA9ICJsb2duMm8iLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgZWZmZWN0cyA9IGMoIm5vM19jYXQiKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHBsb3QgPSBGKQ0KcDIgPC0gY29uZGl0aW9uYWxfZWZmZWN0cyhuMm9fbW9kMywgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIGVmZmVjdHMgPSBjKCJzdXJmdGVtcCIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcGxvdCA9IEYpDQoNCnBsdCA8LSBnZ2FycmFuZ2UocGxvdChwMSwgcGxvdCA9IEYpW1sxXV0sIA0KICAgICAgICAgIHBsb3QocDIsIHBsb3QgPSBGKVtbMV1dLA0KICAgICAgICAgIG5jb2wgPSAyKQ0KDQpybShwMSwgcDIpDQoNCmFubm90YXRlX2ZpZ3VyZShwbHQsIHRvcCA9IHRleHRfZ3JvYigiTjJPOiBjb25kaXRpb25hbCBlZmZlY3RzIiwgDQogICAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIsIGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNCkpDQpgYGANCg0KIyMjIyBFcXVpbGlicml1bSBOMk8NClRoZSBtb2RlbGVkIGVmZmVjdHMgYmVsb3cgZm9yIHRoZSBlcXVpbGlicml1bSBOMk8gY29tcG9uZW50IG9mIHRoZSBtb2RlbCBpbGx1c3RyYXRlZCBhIG5lZ2F0aXZlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGVxdWlsaWJyaXVtIE4yTyBhbmQgYm90aCBwcmVkaWN0b3JzIGFuZCBhbiBpbnRlcmFjdGlvbiBzdWNoIHRoYXQgdGhlIHN1cmZhY2UgdGVtcGVyYXR1cmUgZWZmZWN0IGJlY2FtZSBzbGlnaHRseSBzdGVlcGVyIGF0IGxvd2VyIGVsZXZhdGlvbnMuDQpgYGB7ciBjb25kaXRpb25hbF9lZmZlY3RzX21vZF9uMm9lcTMsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9M30NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2QzLnJkYSIpDQpwMSA8LSBjb25kaXRpb25hbF9lZmZlY3RzKG4yb19tb2QzLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcCA9ICJsb2duMm9lcSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBlZmZlY3RzID0gYygibG9nX2VsZXY6c3VyZnRlbXAiKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHBsb3QgPSBGKQ0KcDIgPC0gY29uZGl0aW9uYWxfZWZmZWN0cyhuMm9fbW9kMywgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgZWZmZWN0cyA9IGMoInN1cmZ0ZW1wOmxvZ19lbGV2IiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90ID0gRikNCg0KcGx0IDwtIGdnYXJyYW5nZShwbG90KHAxLCBwbG90ID0gRilbWzFdXSwNCiAgICAgICAgICAgICAgICAgcGxvdChwMiwgcGxvdCA9IEYpW1sxXV0pDQoNCnJtKHAxLCBwMikNCg0KYW5ub3RhdGVfZmlndXJlKHBsdCwgdG9wID0gdGV4dF9ncm9iKCJFcXVpbGlicml1bSBOMk86IGNvbmRpdGlvbmFsIGVmZmVjdHMiLCANCiAgICAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIiwgZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE0KSkNCmBgYA0KDQojIyBNb2RlbCA0DQpJbiB0aGUgbmV4dCBtb2RlbCwgY292YXJpYXRlIHRlcm1zIHdlcmUgYWxzbyBpbmNsdWRlZCBpbiB0aGUgJFxzaWdtYSQgY29tcG9uZW50cyBvZiBib3RoIG1vZGVscyBpbiBvcmRlciB0byB0cnkgdG8gYmV0dGVyIGNhcHR1cmUgcmVtYWluaW5nIGhldGVyb2dlbmVpdHkgaW4gdGhlIHZhcmlhbmNlcyBvZiBib3RoIE4yTyBhbmQgTjJPLWVxLg0KYGBge3IgbjJvX21vZF9tdl80LCBldmFsPUZBTFNFLCBpbmNsdWRlPVRSVUV9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZl9tb2RlbC5yZGEiKQ0KDQpiZl9uMm8gPC0gYmYobG9nKG4ybykgfiBtbyhubzNfY2F0KSArDQogICAgICAgICAgICAgICBzdXJmdGVtcCArDQogICAgICAgICAgICAgICAobW8obm8zX2NhdCkgfCBhIHwgV1NBOSkgKyANCiAgICAgICAgICAgICAgIChtbyhubzNfY2F0KSB8IGIgfCBXU0E5OnN0YXRlKSArIA0KICAgICAgICAgICAgICAgKDEgfCBjIHwgV1NBOTpzdGF0ZTpzaXplX2NhdCksDQogICAgICAgICAgICAgc2lnbWEgfiBtbyhubzNfY2F0KSArDQogICAgICAgICAgICAgICBzdXJmdGVtcCArDQogICAgICAgICAgICAgICAoMSB8IFdTQTkpICsgDQogICAgICAgICAgICAgICAoMSB8IFdTQTk6c3RhdGUpICsgDQogICAgICAgICAgICAgICAoMSB8IFdTQTk6c3RhdGU6c2l6ZV9jYXQpLCANCiAgICAgICAgICAgICBmYW1pbHkgPSBnYXVzc2lhbigpKQ0KDQpiZl9uMm9lcSA8LSBiZihsb2cobjJvX2VxKSB+IHN1cmZ0ZW1wICsNCiAgICAgICAgICAgICAgICAgbG9nX2VsZXYgKw0KICAgICAgICAgICAgICAgICBzdXJmdGVtcDpsb2dfZWxldiArDQogICAgICAgICAgICAgICAgICgxIHwgYSB8IFdTQTkpICsgDQogICAgICAgICAgICAgICAgICgxIHwgYiB8IFdTQTk6c3RhdGUpICsNCiAgICAgICAgICAgICAgICAgKDEgfCBjIHwgV1NBOTpzdGF0ZTpzaXplX2NhdCksDQogICAgICAgICAgICAgc2lnbWEgfiBzdXJmdGVtcCArDQogICAgICAgICAgICAgICBsb2dfZWxldiArDQogICAgICAgICAgICAgICAoMSB8IFdTQTkpICsgDQogICAgICAgICAgICAgICAoMSB8IFdTQTk6c3RhdGUpICsgDQogICAgICAgICAgICAgICAoMSB8IFdTQTk6c3RhdGU6c2l6ZV9jYXQpLA0KICAgICAgICAgICAgIGZhbWlseSA9IGdhdXNzaWFuKCkpDQoNCnByaW9ycyA8LSBjKA0KICBwcmlvcihub3JtYWwoMiwgMSksIGNsYXNzID0gIkludGVyY2VwdCIsIHJlc3AgPSAibG9nbjJvIiksDQogIHByaW9yKG5vcm1hbCgwLCAxKSwgY2xhc3MgPSAiYiIsIHJlc3AgPSAibG9nbjJvIiksDQogIHByaW9yKGV4cG9uZW50aWFsKDIpLCBjbGFzcyA9ICJzZCIsIHJlc3AgPSAibG9nbjJvIiksDQogIHByaW9yKG5vcm1hbCgtMSwgMiksIGNsYXNzID0gIkludGVyY2VwdCIsIGRwYXIgPSAic2lnbWEiLCByZXNwID0gImxvZ24ybyIpLA0KICBwcmlvcihub3JtYWwoMCwgMSksIGNsYXNzID0gImIiLCBkcGFyID0gInNpZ21hIiwgcmVzcCA9ICJsb2duMm8iKSwNCiAgcHJpb3IoZXhwb25lbnRpYWwoMiksIGNsYXNzID0gInNkIiwgZHBhciA9ICJzaWdtYSIsIHJlc3AgPSAibG9nbjJvIiksDQogIHByaW9yKG5vcm1hbCgyLCAxKSwgY2xhc3MgPSAiSW50ZXJjZXB0IiwgcmVzcCA9ICJsb2duMm9lcSIpLCANCiAgcHJpb3Iobm9ybWFsKDAsIDEpLCBjbGFzcyA9ICJiIiwgcmVzcCA9ICJsb2duMm9lcSIpLCANCiAgcHJpb3IoZXhwb25lbnRpYWwoMiksIGNsYXNzID0gInNkIiwgcmVzcCA9ICJsb2duMm9lcSIpLCANCiAgcHJpb3Iobm9ybWFsKC0xLCAyKSwgY2xhc3MgPSAiSW50ZXJjZXB0IiwgZHBhciA9ICJzaWdtYSIsIHJlc3AgPSAibG9nbjJvZXEiKSwNCiAgcHJpb3Iobm9ybWFsKDAsIDEpLCBjbGFzcyA9ICJiIiwgZHBhciA9ICJzaWdtYSIsIHJlc3AgPSAibG9nbjJvZXEiKSwNCiAgcHJpb3IoZXhwb25lbnRpYWwoMiksIGNsYXNzID0gInNkIiwgZHBhciA9ICJzaWdtYSIsIHJlc3AgPSAibG9nbjJvZXEiKSwNCiAgDQogIHByaW9yKGxraigyKSwgY2xhc3MgPSAicmVzY29yIiksDQogIHByaW9yKGxraigyKSwgY2xhc3MgPSAiY29yIikNCiAgKQ0KDQpuMm9fbW9kNCA8LSBicm0oYmZfbjJvICsgYmZfbjJvZXEgKyBzZXRfcmVzY29yKHJlc2NvciA9IFRSVUUpLA0KICAgICAgICAgICAgICAgIGRhdGEgPSBkZl9tb2RlbCwgDQogICAgICAgICAgICAgICAgcHJpb3IgPSBwcmlvcnMsDQogIGNvbnRyb2wgPSBsaXN0KGFkYXB0X2RlbHRhID0gMC45NzUsIG1heF90cmVlZGVwdGggPSAxMiksDQogICNzYW1wbGVfcHJpb3IgPSAib25seSIsDQogIHNhdmVfcGFycyA9IHNhdmVfcGFycyhhbGwgPSBUUlVFKSwNCiAgc2VlZCA9IDE1ODUxLA0KICBjaGFpbnM9NCwgDQogIGl0ZXI9NTAwMCwgDQogIGNvcmVzPTQpDQoNCnNhdmUobjJvX21vZDQsIGZpbGUgPSAiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDQucmRhIikNCmBgYA0KDQojIyMgU3VtbWFyaXplIGZpdA0KQmVsb3cgaXMgYSBzdW1tYXJ5IG9mIHRoZSBmaXR0ZWQgcGFyYW1ldGVycyBhbG9uZyB3aXRoIHNvbWUgY29udmVyZ2VuY2UgZGlhZ25vc3RpY3MuDQpgYGB7ciBwcmludF9tb2Q0LCBlY2hvPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDQucmRhIikNCg0KcHJpbnQobjJvX21vZDQsIHByaW9yID0gVCwgZGlnaXRzID0gMykNCmBgYA0KDQojIyMgTW9kZWwgY2hlY2tzDQpBZ2FpbiwgdGhlIHNhbWUgUFBDcyB3ZXJlIGVtcGxveWVkIGZvciB0aGlzIG1vZGVsIGFzIGFib3ZlLg0KIyMjIyBEaXNzb2x2ZWQgTjJPDQpBZ2FpbiwgdGhpcyBtb2RlbCBhcHBlYXJlZCB0byBiZSBhbiBpbXByb3ZlbWVudCBvbiB0aGUgcHJldmlvdXMgbW9kZWwsIHBhcnRpY3VsYXJseSB3aXRoIHJlZ2FyZCB0byB0aGUgbW9yZSBjb25zdGFudCB2YXJpYW5jZSBpbmRpY2F0ZWQgaW4gdGhlIG9ic2VydmVkIF92cy5fIHByZWRpY3RlZCBwbG90IChib3R0b20sIHJpZ2h0IHBhbmVsKS4NCmBgYHtyIHBwY19mdWxsX2NoZWNrc19tb2RfbjJvNCwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD04LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDQucmRhIikNCmdyaWQuYXJyYW5nZSgNCnBwX2NoZWNrKG4yb19tb2Q0LCANCiAgICAgICAgIG5kcmF3cyA9IDIwMCwNCiAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgIHR5cGUgPSAiZGVuc19vdmVybGF5IiwNCiAgICAgICAgIG5zYW1wbGVzID0gNDAsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgeGxhYihleHByZXNzaW9uKHBhc3RlKCJsb2coTiJbMl0sIk8pIikpKSArIA0KICB5bGFiKCJkZW5zaXR5IikNCiwNCnBwX2NoZWNrKG4yb19tb2Q0LCANCiAgICAgICAgIG5kcmF3cyA9IDIwMCwNCiAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgIHR5cGUgPSAiZWNkZl9vdmVybGF5IiwNCiAgICAgICAgIG5zYW1wbGVzID0gNDAsIA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKSArDQogIHhsYWIoZXhwcmVzc2lvbihwYXN0ZSgibG9nKE4iWzJdLCJPKSIpKSkgKyANCiAgeWxhYigiY3VtdWxhdGl2ZSBkZW5zaXR5IikNCiwNCnBwX2NoZWNrKG4yb19tb2Q0LCANCiAgICAgICAgIG5kcmF3cyA9IDEwMDAsDQogICAgICAgICByZXNwID0gImxvZ24ybyIsDQogICAgICAgICB0eXBlID0gInN0YXRfMmQiLCANCiAgICAgICAgIHN0YXQgPSBjKCJtZWFuIiwgInNkIiksIA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KcHBfY2hlY2sobjJvX21vZDQsIA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoImt1cnRvc2lzIiwgInNrZXduZXNzIiksIA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KcHBfY2hlY2sobjJvX21vZDQsIA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoIm1pbiIsICJtYXgiKSwgDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpwcF9jaGVjayhuMm9fbW9kNCwgDQogICAgICAgICByZXNwID0gImxvZ24ybyIsDQogICAgICAgICB0eXBlID0gInNjYXR0ZXJfYXZnIiwgDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpDQosIG5jb2wgPSAyKQ0KYGBgDQoNCiMjIyMgRXF1aWxpYnJpdW0gTjJPDQpUaGlzIGNvbXBvbmVudCBvZiB0aGUgbW9kZWwgYWxzbyBzZWVtZWQgdG8gYmUgYW4gaW1wcm92ZW1lbnQgb3ZlciBtb2RlbCAzLCB3aXRoIGJldHRlciByZXByZXNlbnRhdGlvbiBpbiB0aGUgdGFpbHMgYXMgaW5kaWNhdGVkIGluIHRoZSBza2V3bmVzcyBfdnMuXyBrdXJ0b3NpcyBQUEMuIA0KYGBge3IgcHBjX2Z1bGxfY2hlY2tzX21vZF9uMm9lcTQsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q0LnJkYSIpDQpncmlkLmFycmFuZ2UoDQpwcF9jaGVjayhuMm9fbW9kNCwgDQogICAgICAgICBuZHJhd3MgPSAyMDAsDQogICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAiZGVuc19vdmVybGF5IiwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkgKw0KICB4bGFiKGV4cHJlc3Npb24ocGFzdGUoImxvZyhFcXVpbGlicml1bSBOIlsyXSwiTykiKSkpICsgDQogIHlsYWIoImRlbnNpdHkiKQ0KLA0KcHBfY2hlY2sobjJvX21vZDQsIA0KICAgICAgICAgbmRyYXdzID0gMjAwLA0KICAgICAgICAgcmVzcCA9ICJsb2duMm9lcSIsDQogICAgICAgICB0eXBlID0gImVjZGZfb3ZlcmxheSIsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgeGxhYihleHByZXNzaW9uKHBhc3RlKCJsb2coRXF1aWxpYnJpdW0gTiJbMl0sIk8pIikpKSArIA0KICB5bGFiKCJjdW11bGF0aXZlIGRlbnNpdHkiKQ0KLA0KcHBfY2hlY2sobjJvX21vZDQsIA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLA0KICAgICAgICAgdHlwZSA9ICJzdGF0XzJkIiwgDQogICAgICAgICBzdGF0ID0gYygibWVhbiIsICJzZCIpLCANCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2Q0LCANCiAgICAgICAgIG5kcmF3cyA9IDEwMDAsDQogICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoImt1cnRvc2lzIiwgInNrZXduZXNzIiksIA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KcHBfY2hlY2sobjJvX21vZDQsIA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLA0KICAgICAgICAgdHlwZSA9ICJzdGF0XzJkIiwgDQogICAgICAgICBzdGF0ID0gYygibWluIiwgIm1heCIpLCANCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2Q0LCANCiAgICAgICAgIG5kcmF3cyA9IDEwMDAsDQogICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAic2NhdHRlcl9hdmciLCANCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwgbmNvbCA9IDIpDQpgYGANCg0KIyMjIyBCaXZhcmlhdGUNCkFnYWluLCBhbiBpbXByb3ZlbWVudCBvdmVyIHRoZSBwcmV2aW91cyBtb2RlbCB3aXRoIGEgdGlnaHRlciBmaXQgb2YgdGhlIFBQQyB0byB0aGUgb2JzZXJ2ZWQgYml2YXJpYXRlIGRlbnNpdHkuDQpgYGB7ciBwcGNfYnZfY2hlY2tfbW9kX24ybzQsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q0LnJkYSIpDQpkZl9tb2RlbCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kNCwgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gMjApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbG9nKG4yb19vYnMpLCB5ID0gbG9nKG4yb2VxX29icykpKSArDQogIGdlb21fZGVuc2l0eV8yZChhZXMoeCA9IGxvZ24ybywgDQogICAgICAgICAgICAgICAgICAgICAgeSA9IGxvZ24yb2VxLCANCiAgICAgICAgICAgICAgICAgICAgICBncm91cCA9IC5kcmF3KSwNCiAgICAgICAgICAgICAgICAgIGJpbnMgPSAxMCwNCiAgICAgICAgICAgICAgICAgIGNvbG9yID0gImxpZ2h0Ymx1ZSIsIA0KICAgICAgICAgICAgICAgICAgYWxwaGEgPSAwLjQpICsNCiAgZ2VvbV9kZW5zaXR5XzJkKGNvbG9yID0gImJsYWNrIiwgYmlucyA9IDEwKSArDQogIHhsaW0oMS4yNSwgMi43NSkgKw0KICB5bGltKDEuMjUsIDIuNzUpICsNCiAgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIHRoZW1lX3RpZHliYXllcygpDQpgYGANCg0KIyMjIyBTYXR1cmF0aW9uDQpUaGlzIGNoZWNrIGFsc28gc3VnZ2VzdGVkIGFuIGltcHJvdmVtZW50IG92ZXIgdGhlIHByZXZpb3VzIG1vZGVscywgd2l0aCBiZXR0ZXIgdGFpbCBiZWhhdmlvciBhbmQgbGVzcyBiaWFzIGluIHRoZSBwcm9wb3J0aW9uIHVuZGVyLXNhdHVyYXRlZCBtZWFzdXJlLg0KYGBge3IgcHBjX3NhdF9jaGVja19tb2RfbjJvNCwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD04LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDQucmRhIikNCmdyaWQuYXJyYW5nZSgNCmRmX21vZGVsICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2Q0LCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MCkgJT4lDQogIHJlbmFtZShuMm9fb2JzID0gbjJvLA0KICAgICAgICAgbjJvZXFfb2JzID0gbjJvX2VxKSAlPiUNCiAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAuY2F0ZWdvcnksDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gLnByZWRpY3Rpb24pICU+JQ0KICBtdXRhdGUoc2F0X3JhdGlvID0gbjJvX29icyAvIG4yb2VxX29icywNCiAgICAgICAgIHNhdF9wcmVkID0gZXhwKGxvZ24ybykgLyBleHAobG9nbjJvZXEpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gc2F0X3JhdGlvKSkgKw0KICBnZW9tX2RlbnNpdHkoYWVzKHggPSBzYXRfcHJlZCwgZ3JvdXAgPSAuZHJhdyksIA0KICAgICAgICAgICAgICAgbiA9IDEwMjQsIA0KICAgICAgICAgICAgICAgYWRqdXN0ID0gMSwNCiAgICAgICAgICAgICAgIGNvbG9yID0gImxpZ2h0Ymx1ZSIpICsNCiAgZ2VvbV9kZW5zaXR5KG4gPSAxMDI0LCBhZGp1c3QgPSAyKSArDQogIHhsaW0oMCwgNSkgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KZGZfbW9kZWwgJT4lDQogIGFkZF9wcmVkaWN0ZWRfZHJhd3MobjJvX21vZDQsIA0KICAgICAgICAgICAgICAgICAgICAgIG5kcmF3cyA9IDUwMCkgJT4lDQogIHJlbmFtZShuMm9fb2JzID0gbjJvLA0KICAgICAgICAgbjJvZXFfb2JzID0gbjJvX2VxKSAlPiUNCiAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAuY2F0ZWdvcnksDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gLnByZWRpY3Rpb24pICU+JQ0KICBtdXRhdGUodXNhdF9wcmVkID0gaWZlbHNlKGV4cChsb2duMm8pIDwgZXhwKGxvZ24yb2VxKSwgMSwgMCkpICU+JQ0KICBncm91cF9ieSguZHJhdykgJT4lDQogIHN1bW1hcmlzZShwcm9wX3ByZWQgPSBzdW0odXNhdF9wcmVkKSAvIDk4NCkgJT4lDQogIGdncGxvdChhZXMoeCA9IHByb3BfcHJlZCkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjAwMSwgZmlsbCA9ICJsaWdodGJsdWUiKSArDQogIGdlb21fdmxpbmUoZGF0YSA9IGRmX21vZGVsLCBtYXBwaW5nID0gYWVzKHhpbnRlcmNlcHQgPSBzdW0objJvIDwgbjJvX2VxKS85ODQpKSArDQogIHhsYWIoIlByb3BvcnRpb24gdW5kZXJzYXR1cmF0ZWQgd2F0ZXJib2RpZXMiKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpkZl9tb2RlbCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kNCwgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTAwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIG11dGF0ZShzYXRfcmF0aW8gPSBuMm9fb2JzIC8gbjJvZXFfb2JzLA0KICAgICAgICAgc2F0X3ByZWQgPSBleHAobG9nbjJvKSAvIGV4cChsb2duMm9lcSkpICU+JQ0KICBncm91cF9ieSguZHJhdykgJT4lDQogIG11dGF0ZShtZWFuX3lyZXAgPSBtZWFuKHNhdF9wcmVkKSwNCiAgICAgICAgIHNkX3lyZXAgPSBzZChzYXRfcHJlZCkpICU+JSANCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUobWVhbl95ID0gbWVhbihzYXRfcmF0aW8pLA0KICAgICAgICAgc2RfeSA9IHNkKHNhdF9yYXRpbykpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBtZWFuX3lyZXAsIHkgPSBzZF95cmVwKSkgKw0KICBnZW9tX3BvaW50KGNvbG9yID0gImxpZ2h0Ymx1ZSIpICsNCiAgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdCA9IG1lYW5feSksIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IHNkX3kpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpkZl9tb2RlbCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kNCwgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTAwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIG11dGF0ZShzYXRfcmF0aW8gPSBuMm9fb2JzIC8gbjJvZXFfb2JzLA0KICAgICAgICAgc2F0X3ByZWQgPSBleHAobG9nbjJvKSAvIGV4cChsb2duMm9lcSkpICU+JQ0KICBncm91cF9ieSguZHJhdykgJT4lDQogIG11dGF0ZShtaW5feXJlcCA9IG1pbihzYXRfcHJlZCksDQogICAgICAgICBtYXhfeXJlcCA9IG1heChzYXRfcHJlZCkpICU+JSANCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUobWluX3kgPSBtaW4oc2F0X3JhdGlvKSwNCiAgICAgICAgIG1heF95ID0gbWF4KHNhdF9yYXRpbykpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBtaW5feXJlcCwgeSA9IG1heF95cmVwKSkgKw0KICBnZW9tX3BvaW50KGNvbG9yID0gImxpZ2h0Ymx1ZSIpICsNCiAgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdCA9IG1pbl95KSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICBnZW9tX2hsaW5lKGFlcyh5aW50ZXJjZXB0ID0gbWF4X3kpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpkZl9tb2RlbCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kNCwgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTAwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIG11dGF0ZShzYXRfcmF0aW8gPSBuMm9fb2JzIC8gbjJvZXFfb2JzLA0KICAgICAgICAgc2F0X3ByZWQgPSBleHAobG9nbjJvKSAvIGV4cChsb2duMm9lcSkpICU+JQ0KICBncm91cF9ieSgucm93KSAlPiUNCiAgbXV0YXRlKG1lYW5feXJlcCA9IG1lYW4oc2F0X3ByZWQpKSAlPiUgDQogIGZpbHRlciguZHJhdyA9PSAxKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1lYW5feXJlcCwgeSA9IHNhdF9yYXRpbykpICsNCiAgZ2VvbV9wb2ludChjb2xvciA9ICJsaWdodGJsdWUiKSArDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLCBuY29sID0gMikNCmBgYA0KDQojIyMjIFItc3F1YXJlDQpUaGUgQmF5ZXNpYW4gJFJeMiQgZXN0aW1hdGVzIGJlbG93IGluZGljYXRlZCBhbiBpbXByb3ZlbWVudCBmcm9tIHRoZSBwcmV2aW91cyBtb2RlbHMuDQpgYGB7ciByMl9tb2RfbjJvNCwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NCwgZmlnLmhlaWdodD00fQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDQucmRhIikNCnJvdW5kKGJheWVzX1IyKG4yb19tb2Q0LCByZXNwID0gImxvZ24ybyIsIGNvcmVzID0gMSksIDMpIA0Kcm91bmQoYmF5ZXNfUjIobjJvX21vZDQsIHJlc3AgPSAibG9nbjJvZXEiLCBjb3JlcyA9IDEpLCAzKQ0KYGBgDQoNCiMjIyBDb3ZhcmlhdGUgZWZmZWN0cw0KIyMjIyBOMk8NClRoZSBjb25kaXRpb25hbCBlZmZlY3RzIHBsb3RzIGZvciB0aGUgY292YXJpYXRlIGVmZmVjdHMgb24gTjJPIHJlbWFpbmVkIGxhcmdlbHkgdW5jaGFuZ2VkIGZyb20gdGhlIHByZXZpb3VzIG1vZGVsLg0KYGBge3IgY29uZGl0aW9uYWxfZWZmZWN0c19tb2RfbjJvNCwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD0yfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDQucmRhIikNCg0KcDEgPC0gY29uZGl0aW9uYWxfZWZmZWN0cyhuMm9fbW9kNCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIGVmZmVjdHMgPSBjKCJubzNfY2F0IiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90ID0gRikNCnAyIDwtIGNvbmRpdGlvbmFsX2VmZmVjdHMobjJvX21vZDQsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwID0gImxvZ24ybyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBlZmZlY3RzID0gYygic3VyZnRlbXAiKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHBsb3QgPSBGKQ0KDQpwbHQgPC0gZ2dhcnJhbmdlKHBsb3QocDEsIHBsb3QgPSBGKVtbMV1dLCANCiAgICAgICAgICBwbG90KHAyLCBwbG90ID0gRilbWzFdXSwNCiAgICAgICAgICBuY29sID0gMikNCg0Kcm0ocDEsIHAyKQ0KDQphbm5vdGF0ZV9maWd1cmUocGx0LCB0b3AgPSB0ZXh0X2dyb2IoZXhwcmVzc2lvbihwYXN0ZSgiTjJPOiBjb3ZhcmlhdGUgZWZmZWN0cyBvbiAiLCBtdSkpLCANCiAgICAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIiwgZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE0KSkNCmBgYA0KDQpCZWxvdyBhcmUgZXN0aW1hdGVzIG9mIHRoZSBjb25kaXRpb25hbCBlZmZlY3RzIG9mIHRoZSBjb3ZhcmlhdGVzIG9uICRcc2lnbWEkIGZvciBOMk8uIFRoZXNlIHBsb3RzIHN1Z2dlc3RlZCBhIGxhcmdlIGVmZmVjdCBvZiBOTzMgb24gdGhlIHZhcmlhbmNlIG9mIE4yTywgYnV0IGxpdHRsZSB0byBubyBlZmZlY3Qgb2Ygc3VyZmFjZSB0ZW1wZXJhdHVyZS4NCmBgYHtyIGNvbmRpdGlvbmFsX2VmZmVjdHNfc2lnbWFfbjJvNCwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD0yfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDQucmRhIikNCg0KcDEgPC0gY29uZGl0aW9uYWxfZWZmZWN0cyhuMm9fbW9kNCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgZHBhciA9ICJzaWdtYSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGVmZmVjdHMgPSBjKCJubzNfY2F0IiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90ID0gRikNCnAyIDwtIGNvbmRpdGlvbmFsX2VmZmVjdHMobjJvX21vZDQsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwID0gImxvZ24ybyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGRwYXIgPSAic2lnbWEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBlZmZlY3RzID0gYygic3VyZnRlbXAiKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHBsb3QgPSBGKQ0KDQpwbHQgPC0gZ2dhcnJhbmdlKHBsb3QocDEsIHBsb3QgPSBGKVtbMV1dLA0KICAgICAgICAgICAgICAgICBwbG90KHAyLCBwbG90ID0gRilbWzFdXSkNCg0Kcm0ocDEsIHAyKQ0KDQphbm5vdGF0ZV9maWd1cmUocGx0LCANCiAgICAgICAgICAgICAgICB0b3AgPSB0ZXh0X2dyb2IoZXhwcmVzc2lvbihwYXN0ZSgiTjJPOiBjb3ZhcmlhdGUgZWZmZWN0cyBvbiAiLCBzaWdtYSkpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhY2UgPSAiYm9sZCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemUgPSAxNCkpDQpgYGANCg0KIyMjIyBFcXVpbGlicml1bSBOMk8NClRoZSBjb3ZhcmlhdGUgZWZmZWN0cyBvbiBOMk8gcmVtYWluZWQgbGFyZ2VseSB0aGUgc2FtZSBhcyBmb3IgdGhlIHByZXZpb3VzIG1vZGVsLg0KYGBge3IgY29uZGl0aW9uYWxfZWZmZWN0c19tb2RfbjJvZXE0LCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTJ9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kNC5yZGEiKQ0KDQpwMSA8LSBjb25kaXRpb25hbF9lZmZlY3RzKG4yb19tb2Q0LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcCA9ICJsb2duMm9lcSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBlZmZlY3RzID0gYygibG9nX2VsZXY6c3VyZnRlbXAiKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHBsb3QgPSBGKQ0KcDIgPC0gY29uZGl0aW9uYWxfZWZmZWN0cyhuMm9fbW9kNCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgZWZmZWN0cyA9IGMoInN1cmZ0ZW1wOmxvZ19lbGV2IiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90ID0gRikNCnBsdCA8LSBnZ2FycmFuZ2UocGxvdChwMSwgcGxvdCA9IEYpW1sxXV0sDQogICAgICAgICAgICAgICAgIHBsb3QocDIsIHBsb3QgPSBGKVtbMV1dKQ0KDQpybShwMSwgcDIpDQoNCmFubm90YXRlX2ZpZ3VyZShwbHQsIHRvcCA9IHRleHRfZ3JvYihleHByZXNzaW9uKHBhc3RlKCJFcXVpbGlicml1bSBOMk86IGNvdmFyaWF0ZSBlZmZlY3RzIG9uICIsIG11KSksIA0KICAgICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siLCBmYWNlID0gImJvbGQiLCBzaXplID0gMTQpKQ0KYGBgDQoNClRoZSBjb3ZhcmlhdGUgZWZmZWN0cyBvbiAkXHNpZ21hJCBmb3IgTjJPLWVxIHN1Z2dlc3RlZCBhbiBuZWdhdGl2ZSBlZmZlY3Qgb2Ygc3VyZmFjZSB0ZW1wZXJhdHVyZSBhbmQgbGl0dGUgdG8gbm8gZWZmZWN0IG9mIGVsZXZhdGlvbi4NCmBgYHtyIGNvbmRpdGlvbmFsX2VmZmVjdHNfc2lnbWFfbjJvZXE0LCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTJ9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kNC5yZGEiKQ0KDQpwMSA8LSBjb25kaXRpb25hbF9lZmZlY3RzKG4yb19tb2Q0LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcCA9ICJsb2duMm9lcSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGRwYXIgPSAic2lnbWEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBlZmZlY3RzID0gYygic3VyZnRlbXAiKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHBsb3QgPSBGKQ0KcDIgPC0gY29uZGl0aW9uYWxfZWZmZWN0cyhuMm9fbW9kNCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBkcGFyID0gInNpZ21hIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgZWZmZWN0cyA9IGMoImxvZ19lbGV2IiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90ID0gRikNCnBsdCA8LSBnZ2FycmFuZ2UocGxvdChwMSwgcGxvdCA9IEYpW1sxXV0sDQogICAgICAgICAgICAgICAgIHBsb3QocDIsIHBsb3QgPSBGKVtbMV1dKQ0KDQpybShwMSwgcDIpDQoNCmFubm90YXRlX2ZpZ3VyZShwbHQsIHRvcCA9IHRleHRfZ3JvYihleHByZXNzaW9uKHBhc3RlKCJFcXVpbGlicml1bSBOMk86IGNvdmFyaWF0ZSBlZmZlY3RzIG9uICIsIHNpZ21hKSksIA0KICAgICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siLCBmYWNlID0gImJvbGQiLCBzaXplID0gMTQpKQ0KYGBgDQoNCiMjIE1vZGVsIDUNCkluIHRoZSBuZXh0IG1vZGVsLCBtb3JlIGNvbXBsZXhpdHkgaXMgYWRkZWQgdG8gdGhlIE4yTyBjb21wb25lbnQgYnkgaW5jbHVkaW5nIGEgY292YXJpYXRlIGZvciBsYWtlIHN1cmZhY2UgYXJlYSAobG9nIHNjYWxlKSBhcyB3ZWxsIGFzIGludGVyYWN0aW9ucyBiZXR3ZWVuIE5PMyBhbmQgbG9nKGFyZWEpIGFuZCBzdXJmYWNlIHRlbXBlcmF0dXJlLiANCmBgYHtyIG4yb19tb2RfbXZfNSwgZXZhbD1GQUxTRSwgaW5jbHVkZT1UUlVFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvZGZfbW9kZWwucmRhIikNCg0KYmZfbjJvIDwtIGJmKGxvZyhuMm8pIH4gbW8obm8zX2NhdCkgKw0KICAgICAgICAgICAgICAgbG9nX2FyZWEgKw0KICAgICAgICAgICAgICAgc3VyZnRlbXAgKyANCiAgICAgICAgICAgICAgIG1vKG5vM19jYXQpOmxvZ19hcmVhICsNCiAgICAgICAgICAgICAgIG1vKG5vM19jYXQpOnN1cmZ0ZW1wICsNCiAgICAgICAgICAgICAgIChtbyhubzNfY2F0KSB8IGEgfCBXU0E5KSArIA0KICAgICAgICAgICAgICAgKG1vKG5vM19jYXQpIHwgYiB8IFdTQTk6c3RhdGUpICsgDQogICAgICAgICAgICAgICAoMSB8IGMgfCBXU0E5OnN0YXRlOnNpemVfY2F0KSwNCiAgICAgICAgICAgICBzaWdtYSB+IGxvZ19hcmVhICsNCiAgICAgICAgICAgICAgIG1vKG5vM19jYXQpICsNCiAgICAgICAgICAgICAgICgxIHwgV1NBOSkgKyANCiAgICAgICAgICAgICAgICgxIHwgV1NBOTpzdGF0ZSkgKyANCiAgICAgICAgICAgICAgICgxIHwgV1NBOTpzdGF0ZTpzaXplX2NhdCksIA0KICAgICAgICAgICAgIGZhbWlseSA9IGdhdXNzaWFuKCkpDQoNCmJmX24yb2VxIDwtIGJmKGxvZyhuMm9fZXEpIH4gc3VyZnRlbXAgKw0KICAgICAgICAgICAgICAgICBsb2dfZWxldiArDQogICAgICAgICAgICAgICAgIHN1cmZ0ZW1wOmxvZ19lbGV2ICsNCiAgICAgICAgICAgICAgICAgKDEgfCBhIHwgV1NBOSkgKyANCiAgICAgICAgICAgICAgICAgKDEgfCBiIHwgV1NBOTpzdGF0ZSkgKw0KICAgICAgICAgICAgICAgICAoMSB8IGMgfCBXU0E5OnN0YXRlOnNpemVfY2F0KSwNCiAgICAgICAgICAgICBzaWdtYSB+IHN1cmZ0ZW1wICsNCiAgICAgICAgICAgICAgIGxvZ19lbGV2ICsNCiAgICAgICAgICAgICAgICgxIHwgV1NBOSkgKyANCiAgICAgICAgICAgICAgICgxIHwgV1NBOTpzdGF0ZSkgKyANCiAgICAgICAgICAgICAgICgxIHwgV1NBOTpzdGF0ZTpzaXplX2NhdCksDQogICAgICAgICAgICAgZmFtaWx5ID0gZ2F1c3NpYW4oKSkNCg0KcHJpb3JzIDwtIGMoDQogIHByaW9yKG5vcm1hbCgyLCAxKSwgY2xhc3MgPSAiSW50ZXJjZXB0IiwgcmVzcCA9ICJsb2duMm8iKSwNCiAgcHJpb3Iobm9ybWFsKDAsIDEpLCBjbGFzcyA9ICJiIiwgcmVzcCA9ICJsb2duMm8iKSwNCiAgcHJpb3IoZXhwb25lbnRpYWwoMiksIGNsYXNzID0gInNkIiwgcmVzcCA9ICJsb2duMm8iKSwNCiAgcHJpb3Iobm9ybWFsKC0xLCAyKSwgY2xhc3MgPSAiSW50ZXJjZXB0IiwgZHBhciA9ICJzaWdtYSIsIHJlc3AgPSAibG9nbjJvIiksDQogIHByaW9yKG5vcm1hbCgwLCAxKSwgY2xhc3MgPSAiYiIsIGRwYXIgPSAic2lnbWEiLCByZXNwID0gImxvZ24ybyIpLA0KICBwcmlvcihleHBvbmVudGlhbCgyKSwgY2xhc3MgPSAic2QiLCBkcGFyID0gInNpZ21hIiwgcmVzcCA9ICJsb2duMm8iKSwNCiAgDQogIHByaW9yKG5vcm1hbCgyLCAxKSwgY2xhc3MgPSAiSW50ZXJjZXB0IiwgcmVzcCA9ICJsb2duMm9lcSIpLCANCiAgcHJpb3Iobm9ybWFsKDAsIDEpLCBjbGFzcyA9ICJiIiwgcmVzcCA9ICJsb2duMm9lcSIpLCANCiAgcHJpb3IoZXhwb25lbnRpYWwoMiksIGNsYXNzID0gInNkIiwgcmVzcCA9ICJsb2duMm9lcSIpLCANCiAgcHJpb3Iobm9ybWFsKC0xLCAyKSwgY2xhc3MgPSAiSW50ZXJjZXB0IiwgZHBhciA9ICJzaWdtYSIsIHJlc3AgPSAibG9nbjJvZXEiKSwNCiAgcHJpb3Iobm9ybWFsKDAsIDEpLCBjbGFzcyA9ICJiIiwgZHBhciA9ICJzaWdtYSIsIHJlc3AgPSAibG9nbjJvZXEiKSwNCiAgcHJpb3IoZXhwb25lbnRpYWwoMiksIGNsYXNzID0gInNkIiwgZHBhciA9ICJzaWdtYSIsIHJlc3AgPSAibG9nbjJvZXEiKSwNCiAgDQogIHByaW9yKGxraigyKSwgY2xhc3MgPSAicmVzY29yIiksDQogIHByaW9yKGxraigyKSwgY2xhc3MgPSAiY29yIikNCiAgKQ0KDQpuMm9fbW9kNSA8LSBicm0oYmZfbjJvICsgDQogICAgICAgICAgICAgICAgICBiZl9uMm9lcSArDQogICAgICAgICAgICAgICAgICBzZXRfcmVzY29yKHJlc2NvciA9IFRSVUUpLA0KICAgICAgICAgICAgICAgIGRhdGEgPSBkZl9tb2RlbCwgDQogICAgICAgICAgICAgICAgcHJpb3IgPSBwcmlvcnMsDQogIGNvbnRyb2wgPSBsaXN0KGFkYXB0X2RlbHRhID0gMC45NzUsIG1heF90cmVlZGVwdGggPSAxMiksDQogICNzYW1wbGVfcHJpb3IgPSAib25seSIsDQogIHNhdmVfcGFycyA9IHNhdmVfcGFycyhhbGwgPSBUUlVFKSwNCiAgc2VlZCA9IDU0NzQxLA0KICBjaGFpbnM9NCwgDQogIGl0ZXI9NTAwMCwgDQogIGNvcmVzPTQpDQoNCnNhdmUobjJvX21vZDUsIGZpbGUgPSAiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDUucmRhIikNCmBgYA0KDQojIyMgU3VtbWFyaXplIGZpdA0KQmVsb3cgaXMgYSBzdW1tYXJ5IG9mIHRoZSBmaXR0ZWQgcGFyYW1ldGVycyBhbG9uZyB3aXRoIE1DTUMgY29udmVyZ2VuY2UgZGlhZ25vc3RpY3MuDQpgYGB7ciBwcmludF9tb2Q1LCBlY2hvPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDUucmRhIikNCg0KcHJpbnQobjJvX21vZDUsIHByaW9yID0gVCwgZGlnaXRzID0gMykNCmBgYA0KDQojIyMgTW9kZWwgY2hlY2tzDQpBZ2FpbiwgdGhlIHNhbWUgUFBDcyBhcyBhYm92ZSB3ZXJlIHBlcmZvcm1lZCBmb3IgdGhpcyBtb2RlbC4NCiMjIyMgTjJPIFBQQw0KVGhpcyBQUEMgZm9yIE4yTyBsb29rZWQgc2ltaWxhciB0byB0aGUgcHJldmlvdXMgbW9kZWwuDQpgYGB7ciBwcGNfZnVsbF9jaGVja3NfbW9kX24ybzUsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q1LnJkYSIpDQpncmlkLmFycmFuZ2UoDQpwcF9jaGVjayhuMm9fbW9kNSwgDQogICAgICAgICBuZHJhd3MgPSAyMDAsDQogICAgICAgICByZXNwID0gImxvZ24ybyIsDQogICAgICAgICB0eXBlID0gImRlbnNfb3ZlcmxheSIsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgeGxhYihleHByZXNzaW9uKHBhc3RlKCJsb2coTiJbMl0sIk8pIGNvbmNlbnRyYXRpb24iKSkpICsgDQogIHlsYWIoImRlbnNpdHkiKQ0KLA0KcHBfY2hlY2sobjJvX21vZDUsIA0KICAgICAgICAgbmRyYXdzID0gMjAwLA0KICAgICAgICAgcmVzcCA9ICJsb2duMm8iLA0KICAgICAgICAgdHlwZSA9ICJlY2RmX292ZXJsYXkiLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKSArDQogIHhsYWIoZXhwcmVzc2lvbihwYXN0ZSgibG9nKE4iWzJdLCJPKSBjb25jZW50cmF0aW9uIikpKSArIA0KICB5bGFiKCJjdW11bGF0aXZlIGRlbnNpdHkiKQ0KLA0KcHBfY2hlY2sobjJvX21vZDUsIA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoIm1lYW4iLCAic2QiKSwgDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpwcF9jaGVjayhuMm9fbW9kNSwgDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgcmVzcCA9ICJsb2duMm8iLA0KICAgICAgICAgdHlwZSA9ICJzdGF0XzJkIiwgDQogICAgICAgICBzdGF0ID0gYygia3VydG9zaXMiLCAic2tld25lc3MiKSwgDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpwcF9jaGVjayhuMm9fbW9kNSwgDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgcmVzcCA9ICJsb2duMm8iLA0KICAgICAgICAgdHlwZSA9ICJzdGF0XzJkIiwgDQogICAgICAgICBzdGF0ID0gYygibWluIiwgIm1heCIpLCANCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2Q1LCANCiAgICAgICAgIG5kcmF3cyA9IDEwMDAsDQogICAgICAgICByZXNwID0gImxvZ24ybyIsDQogICAgICAgICB0eXBlID0gInNjYXR0ZXJfYXZnIiwgDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpDQosIG5jb2wgPSAyKQ0KYGBgDQoNCiMjIyMgRXF1aWxpYnJpdW0gTjJPDQpBZ2FpbiwgdGhlIFBQQ3MgZm9yIHRoaXMgbW9kZWwgd2VyZSBzaW1pbGFyIHRvIHRoZSBwcmV2aW91cyBtb2RlbCwgd2hpY2ggd2FzIHVuc3VycHJpc2luZyBnaXZlbiB0aGF0IGl0IHdhcyB0aGUgc2FtZSBtb2RlbCBmb3IgTjJPLWVxLg0KYGBge3IgcHBjX2Z1bGxfY2hlY2tzX21vZF9uMm9lcTUsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q1LnJkYSIpDQpncmlkLmFycmFuZ2UoDQpwcF9jaGVjayhuMm9fbW9kNSwgDQogICAgICAgICBuZHJhd3MgPSAyMDAsDQogICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAiZGVuc19vdmVybGF5IiwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkgKw0KICB4bGFiKGV4cHJlc3Npb24ocGFzdGUoImxvZyhFcXVpbGlicml1bSBOIlsyXSwiTykgY29uY2VudHJhdGlvbiIpKSkgKyANCiAgeWxhYigiZGVuc2l0eSIpDQosDQpwcF9jaGVjayhuMm9fbW9kNSwgDQogICAgICAgICBuZHJhd3MgPSAyMDAsDQogICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAiZWNkZl9vdmVybGF5IiwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkgKw0KICB4bGFiKGV4cHJlc3Npb24ocGFzdGUoImxvZyhFcXVpbGlicml1bSBOIlsyXSwiTykgY29uY2VudHJhdGlvbiIpKSkgKyANCiAgeWxhYigiY3VtdWxhdGl2ZSBkZW5zaXR5IikNCiwNCnBwX2NoZWNrKG4yb19tb2Q1LCANCiAgICAgICAgIG5kcmF3cyA9IDEwMDAsDQogICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoIm1lYW4iLCAic2QiKSwgDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpwcF9jaGVjayhuMm9fbW9kNSwgDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgcmVzcCA9ICJsb2duMm9lcSIsDQogICAgICAgICB0eXBlID0gInN0YXRfMmQiLCANCiAgICAgICAgIHN0YXQgPSBjKCJrdXJ0b3NpcyIsICJza2V3bmVzcyIpLCANCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2Q1LCANCiAgICAgICAgIG5kcmF3cyA9IDEwMDAsDQogICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoIm1pbiIsICJtYXgiKSwgDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpwcF9jaGVjayhuMm9fbW9kNSwgDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgcmVzcCA9ICJsb2duMm9lcSIsDQogICAgICAgICB0eXBlID0gInNjYXR0ZXJfYXZnIiwgDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpDQosIG5jb2wgPSAyKQ0KYGBgDQoNCiMjIyMgQml2YXJpYXRlDQpUaGlzIFBQQyB3YXMgYWxzbyBzaW1pbGFyIHRvIHRoZSBwcmV2aW91cyBtb2RlbC4NCmBgYHtyIHBwY19idl9jaGVja19tb2RfbjJvNSwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD00LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDUucmRhIikNCmRmX21vZGVsICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2Q1LCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSAyMCkgJT4lDQogIHJlbmFtZShuMm9fb2JzID0gbjJvLA0KICAgICAgICAgbjJvZXFfb2JzID0gbjJvX2VxKSAlPiUNCiAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAuY2F0ZWdvcnksDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gLnByZWRpY3Rpb24pICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBsb2cobjJvX29icyksIHkgPSBsb2cobjJvZXFfb2JzKSkpICsNCiAgZ2VvbV9kZW5zaXR5XzJkKGFlcyh4ID0gbG9nbjJvLCANCiAgICAgICAgICAgICAgICAgICAgICB5ID0gbG9nbjJvZXEsIA0KICAgICAgICAgICAgICAgICAgICAgIGdyb3VwID0gLmRyYXcpLA0KICAgICAgICAgICAgICAgICAgYmlucyA9IDEwLA0KICAgICAgICAgICAgICAgICAgY29sb3IgPSAibGlnaHRibHVlIiwgDQogICAgICAgICAgICAgICAgICBhbHBoYSA9IDAuNCkgKw0KICBnZW9tX2RlbnNpdHlfMmQoY29sb3IgPSAiYmxhY2siLCBiaW5zID0gMTApICsNCiAgeGxpbSgxLjI1LCAyLjc1KSArDQogIHlsaW0oMS4yNSwgMi43NSkgKw0KICBnZW9tX2FibGluZShpbnRlcmNlcHQgPSAwLCBzbG9wZSA9IDEsIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCmBgYA0KDQojIyMjIFNhdHVyYXRpb24NClRoaXMgY2hlY2sgd2FzIGFsc28gc2ltaWxhciB0byB0aGUgcHJldm9pdXMgbW9kZWwsIHdpdGggcGVyaGFwcyBzbGlnaHRseSBsZXNzIGJpYXMgaW4gdGhlIHByb3BvcnRpb24gdW5zYXR1cmF0ZWQgZXN0aW1hdGVzLiBUaGVyZSBpcyBhbHNvIGEgcG90ZW50aWFsbHkgY29uY2VybmluZyBleHRyZW1lIHByZWRpY3Rpb24gaW4gdGhlIG9ic2VydmVkIF92c18gcHJlZGljdGVkIFBQQy4NCmBgYHtyIHBwY19zYXRfY2hlY2tfbW9kX24ybzUsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q1LnJkYSIpDQpncmlkLmFycmFuZ2UoDQpkZl9tb2RlbCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kNSwgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgbXV0YXRlKHNhdF9yYXRpbyA9IG4yb19vYnMgLyBuMm9lcV9vYnMsDQogICAgICAgICBzYXRfcHJlZCA9IGV4cChsb2duMm8pIC8gZXhwKGxvZ24yb2VxKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHNhdF9yYXRpbykpICsNCiAgZ2VvbV9kZW5zaXR5KGFlcyh4ID0gc2F0X3ByZWQsIGdyb3VwID0gLmRyYXcpLCANCiAgICAgICAgICAgICAgIG4gPSAxMDI0LCANCiAgICAgICAgICAgICAgIGFkanVzdCA9IDEsDQogICAgICAgICAgICAgICBjb2xvciA9ICJsaWdodGJsdWUiKSArDQogIGdlb21fZGVuc2l0eShuID0gMTAyNCwgYWRqdXN0ID0gMikgKw0KICB4bGltKDAsIDUpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCmRmX21vZGVsICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2Q1LCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MDApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgbXV0YXRlKHVzYXRfcHJlZCA9IGlmZWxzZShleHAobG9nbjJvKSA8IGV4cChsb2duMm9lcSksIDEsIDApKSAlPiUNCiAgZ3JvdXBfYnkoLmRyYXcpICU+JQ0KICBzdW1tYXJpc2UocHJvcF9wcmVkID0gc3VtKHVzYXRfcHJlZCkgLyA5ODQpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBwcm9wX3ByZWQpKSArDQogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC4wMDEsIGZpbGwgPSAibGlnaHRibHVlIikgKw0KICBnZW9tX3ZsaW5lKGRhdGEgPSBkZl9tb2RlbCwgbWFwcGluZyA9IGFlcyh4aW50ZXJjZXB0ID0gc3VtKG4ybyA8IG4yb19lcSkvOTg0KSkgKw0KICB4bGFiKCJQcm9wb3J0aW9uIHVuZGVyc2F0dXJhdGVkIHdhdGVyYm9kaWVzIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KZGZfbW9kZWwgJT4lDQogIGFkZF9wcmVkaWN0ZWRfZHJhd3MobjJvX21vZDUsIA0KICAgICAgICAgICAgICAgICAgICAgIG5kcmF3cyA9IDUwMCkgJT4lDQogIHJlbmFtZShuMm9fb2JzID0gbjJvLA0KICAgICAgICAgbjJvZXFfb2JzID0gbjJvX2VxKSAlPiUNCiAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAuY2F0ZWdvcnksDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gLnByZWRpY3Rpb24pICU+JQ0KICBtdXRhdGUoc2F0X3JhdGlvID0gbjJvX29icyAvIG4yb2VxX29icywNCiAgICAgICAgIHNhdF9wcmVkID0gZXhwKGxvZ24ybykgLyBleHAobG9nbjJvZXEpKSAlPiUNCiAgZ3JvdXBfYnkoLmRyYXcpICU+JQ0KICBtdXRhdGUobWVhbl95cmVwID0gbWVhbihzYXRfcHJlZCksDQogICAgICAgICBzZF95cmVwID0gc2Qoc2F0X3ByZWQpKSAlPiUgDQogIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlKG1lYW5feSA9IG1lYW4oc2F0X3JhdGlvKSwNCiAgICAgICAgIHNkX3kgPSBzZChzYXRfcmF0aW8pKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbWVhbl95cmVwLCB5ID0gc2RfeXJlcCkpICsNCiAgZ2VvbV9wb2ludChjb2xvciA9ICJsaWdodGJsdWUiKSArDQogIGdlb21fdmxpbmUoYWVzKHhpbnRlcmNlcHQgPSBtZWFuX3kpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIGdlb21faGxpbmUoYWVzKHlpbnRlcmNlcHQgPSBzZF95KSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KZGZfbW9kZWwgJT4lDQogIGFkZF9wcmVkaWN0ZWRfZHJhd3MobjJvX21vZDUsIA0KICAgICAgICAgICAgICAgICAgICAgIG5kcmF3cyA9IDUwMCkgJT4lDQogIHJlbmFtZShuMm9fb2JzID0gbjJvLA0KICAgICAgICAgbjJvZXFfb2JzID0gbjJvX2VxKSAlPiUNCiAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAuY2F0ZWdvcnksDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gLnByZWRpY3Rpb24pICU+JQ0KICBtdXRhdGUoc2F0X3JhdGlvID0gbjJvX29icyAvIG4yb2VxX29icywNCiAgICAgICAgIHNhdF9wcmVkID0gZXhwKGxvZ24ybykgLyBleHAobG9nbjJvZXEpKSAlPiUNCiAgZ3JvdXBfYnkoLmRyYXcpICU+JQ0KICBtdXRhdGUobWluX3lyZXAgPSBtaW4oc2F0X3ByZWQpLA0KICAgICAgICAgbWF4X3lyZXAgPSBtYXgoc2F0X3ByZWQpKSAlPiUgDQogIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlKG1pbl95ID0gbWluKHNhdF9yYXRpbyksDQogICAgICAgICBtYXhfeSA9IG1heChzYXRfcmF0aW8pKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbWluX3lyZXAsIHkgPSBtYXhfeXJlcCkpICsNCiAgZ2VvbV9wb2ludChjb2xvciA9ICJsaWdodGJsdWUiKSArDQogIGdlb21fdmxpbmUoYWVzKHhpbnRlcmNlcHQgPSBtaW5feSksIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IG1heF95KSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KZGZfbW9kZWwgJT4lDQogIGFkZF9wcmVkaWN0ZWRfZHJhd3MobjJvX21vZDUsIA0KICAgICAgICAgICAgICAgICAgICAgIG5kcmF3cyA9IDUwMCkgJT4lDQogIHJlbmFtZShuMm9fb2JzID0gbjJvLA0KICAgICAgICAgbjJvZXFfb2JzID0gbjJvX2VxKSAlPiUNCiAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAuY2F0ZWdvcnksDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gLnByZWRpY3Rpb24pICU+JQ0KICBtdXRhdGUoc2F0X3JhdGlvID0gbjJvX29icyAvIG4yb2VxX29icywNCiAgICAgICAgIHNhdF9wcmVkID0gZXhwKGxvZ24ybykgLyBleHAobG9nbjJvZXEpKSAlPiUNCiAgZ3JvdXBfYnkoLnJvdykgJT4lDQogIG11dGF0ZShtZWFuX3lyZXAgPSBtZWFuKHNhdF9wcmVkKSkgJT4lIA0KICBmaWx0ZXIoLmRyYXcgPT0gMSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBtZWFuX3lyZXAsIHkgPSBzYXRfcmF0aW8pKSArDQogIGdlb21fcG9pbnQoY29sb3IgPSAibGlnaHRibHVlIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBnZW9tX2FibGluZShpbnRlcmNlcHQgPSAwLCBzbG9wZSA9IDEsIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwgbmNvbCA9IDIpDQpgYGANCg0KIyMjIyBSLXNxdWFyZQ0KYGBge3IgcjJfbW9kX24ybzUsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTQsIGZpZy5oZWlnaHQ9NH0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q1LnJkYSIpDQpyb3VuZChiYXllc19SMihuMm9fbW9kNSwgcmVzcCA9ICJsb2duMm8iLCBjb3JlcyA9IDEpLCAzKSANCnJvdW5kKGJheWVzX1IyKG4yb19tb2Q1LCByZXNwID0gImxvZ24yb2VxIiwgY29yZXMgPSAxKSwgMykNCmBgYA0KDQojIyMgQ292YXJpYXRlIGVmZmVjdHMNCiMjIyMgTjJPDQpUaGUgY29uZGl0aW9uYWwgZWZmZWN0cyBwbG90IGZvciB0aGUgY292YXJpYXRlIGVmZmVjdHMgTjJPIHN1Z2dlc3RlZCBhIHNpbWlsYXIgZWZmZWN0IG9mIE5PMywgYnV0IGludGVyZXN0aW5nIGludGVyYWN0aW9ucyBiZXR3ZWVuIE5PMyBhbmQgbGFrZSBhcmVhIGFuZCBOTzMgYW5kIHN1cmZhY2UgdGVtcGVyYXR1cmUuIEZvciBsYWtlIGFyZWEsIHRoZSBlZmZlY3Qgd2FzIGVzdGltYXRlZCB0byBiZSBsYXJnZXIgYW5kIG1vcmUgbmVnYXRpdmUgYXQgdGhlIGhpZ2hlc3QgbGV2ZWxzIG9mIE5PMzsgYW5kIHNsaWdodGx5IG5lZ2F0aXZlIGF0IHRoZSBsb3dlc3QgbGV2ZWwgb2YgTk8zLiBGb3Igc3VyZmFjZSB0ZW1wZXJhdHVyZSwgdGhlIGVmZmVjdCB3YXMgZXN0aW1hdGVkIHRvIGJlIGxhcmdlc3QgYW5kIHBvc2l0aXZlIGF0IHRoZSBoaWdoZXN0IGxldmVsIG9mIE5PMzsgYW5kIG5lZ2F0aXZlIGF0IHRoZSBsb3dlc3QgbGV2ZWwgb2YgTk8zLg0KYGBge3IgY29uZGl0aW9uYWxfZWZmZWN0c19tb2RfbjJvNSwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD00fQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDUucmRhIikNCg0KcDEgPC0gY29uZGl0aW9uYWxfZWZmZWN0cyhuMm9fbW9kNSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIGVmZmVjdHMgPSBjKCJubzNfY2F0IiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90ID0gRikNCg0KcDIgPC0gY29uZGl0aW9uYWxfZWZmZWN0cyhuMm9fbW9kNSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIGVmZmVjdHMgPSBjKCJsb2dfYXJlYTpubzNfY2F0IiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90ID0gRikNCnAzIDwtIGNvbmRpdGlvbmFsX2VmZmVjdHMobjJvX21vZDUsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwID0gImxvZ24ybyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBlZmZlY3RzID0gYygic3VyZnRlbXA6bm8zX2NhdCIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcGxvdCA9IEYpDQoNCnBsdCA8LSBnZ2FycmFuZ2UocGxvdChwMSwgcGxvdCA9IEYpW1sxXV0sIA0KICAgICAgICAgICAgICAgICBwbG90KHAyLCBwbG90ID0gRilbWzFdXSwNCiAgICAgICAgICAgICAgICAgcGxvdChwMywgcGxvdCA9IEYpW1sxXV0pDQoNCnJtKHAxLCBwMiwgcDMpDQoNCmFubm90YXRlX2ZpZ3VyZShwbHQsIHRvcCA9IHRleHRfZ3JvYihleHByZXNzaW9uKHBhc3RlKCJOMk86IGNvdmFyaWF0ZSBlZmZlY3RzIG9uICIsIG11KSksIA0KICAgICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siLCBmYWNlID0gImJvbGQiLCBzaXplID0gMTQpKQ0KYGBgDQoNClRoZSBlc3RpbWF0ZWQgY292YXJpYXRlIGVmZmVjdHMgb24gJFxzaWdtYSQgc3VnZ2VzdGVkIGEgbmVnYXRpdmUgcmVsYXRpb25zaGlwIHdpdGggbG9nKGFyZWEpIGFuZCBhIHBvc2l0aXZlIHJlbGF0aW9uc2hpcCwgYWdhaW4sIHdpdGggTk8zLg0KYGBge3IgY29uZGl0aW9uYWxfZWZmZWN0c19zaWdtYV9uMm81LCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTJ9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kNS5yZGEiKQ0KDQpwMSA8LSBjb25kaXRpb25hbF9lZmZlY3RzKG4yb19tb2Q1LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcCA9ICJsb2duMm8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBkcGFyID0gInNpZ21hIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgZWZmZWN0cyA9IGMoImxvZ19hcmVhIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgIHBsb3QgPSBGKQ0KDQpwMiA8LSBjb25kaXRpb25hbF9lZmZlY3RzKG4yb19tb2Q1LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcCA9ICJsb2duMm8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBkcGFyID0gInNpZ21hIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgZWZmZWN0cyA9IGMoIm5vM19jYXQiKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHBsb3QgPSBGKQ0KDQpwbHQgPC0gZ2dhcnJhbmdlKHBsb3QocDEsIHBsb3QgPSBGKVtbMV1dLA0KICAgICAgICAgICAgICAgICBwbG90KHAyLCBwbG90ID0gRilbWzFdXSkNCg0Kcm0ocDEsIHAyKQ0KDQphbm5vdGF0ZV9maWd1cmUocGx0LCANCiAgICAgICAgICAgICAgICB0b3AgPSB0ZXh0X2dyb2IoZXhwcmVzc2lvbihwYXN0ZSgiTjJPOiBjb3ZhcmlhdGUgZWZmZWN0cyBvbiAiLCBzaWdtYSkpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhY2UgPSAiYm9sZCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemUgPSAxNCkpDQpgYGANCg0KIyMjIyBFcXVpbGlicml1bSBOMk8NClRoZSBlc3RpbWF0ZWQgY292YXJpYXRlIGVmZmVjdCBvbiBOMk8gcmVtYWluZWQgbGFyZ2VseSB0aGUgc2FtZSBhcyBlc3RpbWF0ZWQgaW4gdGhlIHByZXZpb3VzIG1vZGVsLg0KYGBge3IgY29uZGl0aW9uYWxfZWZmZWN0c19tb2RfbjJvZXE1LCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTJ9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kNS5yZGEiKQ0KDQpwMSA8LSBjb25kaXRpb25hbF9lZmZlY3RzKG4yb19tb2Q1LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcCA9ICJsb2duMm9lcSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBlZmZlY3RzID0gYygic3VyZnRlbXA6bG9nX2VsZXYiKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHBsb3QgPSBGKQ0KDQpwMiA8LSBjb25kaXRpb25hbF9lZmZlY3RzKG4yb19tb2Q1LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcCA9ICJsb2duMm9lcSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBlZmZlY3RzID0gYygibG9nX2VsZXY6c3VyZnRlbXAiKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHBsb3QgPSBGKQ0KDQpwbHQgPC0gZ2dhcnJhbmdlKHBsb3QocDEsIHBsb3QgPSBGKVtbMV1dLA0KICAgICAgICAgICAgICAgICBwbG90KHAyLCBwbG90ID0gRilbWzFdXSkNCg0Kcm0ocDEsIHAyKQ0KDQphbm5vdGF0ZV9maWd1cmUocGx0LCB0b3AgPSB0ZXh0X2dyb2IoZXhwcmVzc2lvbihwYXN0ZSgiRXF1aWxpYnJpdW0gTjJPOiBjb3ZhcmlhdGUgZWZmZWN0cyBvbiAiLCBtdSkpLCANCiAgICAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIiwgZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE0KSkNCmBgYA0KDQpgYGB7ciBjb25kaXRpb25hbF9lZmZlY3RzX3NpZ21hX24yb2VxNSwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD0yfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDUucmRhIikNCg0KcDEgPC0gY29uZGl0aW9uYWxfZWZmZWN0cyhuMm9fbW9kNSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBkcGFyID0gInNpZ21hIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgZWZmZWN0cyA9IGMoInN1cmZ0ZW1wIiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90ID0gRikNCg0KcDIgPC0gY29uZGl0aW9uYWxfZWZmZWN0cyhuMm9fbW9kNSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBkcGFyID0gInNpZ21hIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgZWZmZWN0cyA9IGMoImxvZ19lbGV2IiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90ID0gRikNCg0KcGx0IDwtIGdnYXJyYW5nZShwbG90KHAxLCBwbG90ID0gRilbWzFdXSwNCiAgICAgICAgICAgICAgICAgcGxvdChwMiwgcGxvdCA9IEYpW1sxXV0pDQoNCnJtKHAxLCBwMikNCg0KYW5ub3RhdGVfZmlndXJlKHBsdCwgdG9wID0gdGV4dF9ncm9iKGV4cHJlc3Npb24ocGFzdGUoIkVxdWlsaWJyaXVtIE4yTzogY292YXJpYXRlIGVmZmVjdHMgb24gIiwgc2lnbWEpKSwgDQogICAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIsIGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNCkpDQpgYGANCg0KIyMgQSBGaW5hbCBNb2RlbA0KQXMgZGVtb25zdHJhdGVkIGFib3ZlLCBtb2RlbHMgZXhjbHVkaW5nIHRoZSBOTzMgY292YXJpYXRlIGNvbnNpc3RlbnRseSByZXN1bHRlZCBpbiBwb29yZXIgZml0cyB0byB0byB0aGUgb2JzZXJ2ZWQgZGlzc29sdmVkIE4yTyBkYXRhLiBJbmNsdWRpbmcgc3VyZmFjZSB0ZW1wZXJhdHVyZSBhbmQgZWxldmF0aW9uIGluIHRoZSBlcXVpbGlicml1bSBOMk8gcGFydCBvZiB0aGUgbW9kZWwgcmVzdWx0ZWQgaW4gc3Vic3RhbnRpYWxseSBpbXByb3ZlZCByZXBsaWNhdGlvbiBvZiBrZXkgYXNwZWN0cyBvZiB0aGUgb2JzZXJ2ZWQgZGF0YS4gTGlrZXdpc2UsIGFkZGVkIGZsZXhpYmlsaXR5IGluIHRoZSBkaXN0cmlidXRpb25hbCB0ZXJtcyBmb3IgYm90aCBkaXNzb2x2ZWQgYW5kIGVxdWlsaWJyaXVtIE4yTyBsZWQgdG8gaW1wcm92ZW1lbnRzLiANCg0KVG8gbWFrZSBpbmZlcmVuY2VzIGZyb20gdGhpcyBtb2RlbCBmb3IgTjJPIGluIHRoZSBwb3B1bGF0aW9uIG9mIGludGVyZXN0LCBob3dldmVyLCB0aGUgaW5jbHVkZWQgY292YXJpYXRlcyBuZWVkZWQgdG8gYmUgKDEpIGZ1bGx5IG9ic2VydmVkIGFjcm9zcyB0aGF0IHBvcHVsYXRpb24gb3IgKDIpIHRoZWlyIG1pc3NpbmduZXNzIG5lZWRlZCB0byBiZSBtb2RlbGVkLiBGb3IgdGhlIGxha2UgYXJlYSBhbmQgZWxldmF0aW9uIGNvdmFyaWF0ZXMsIGRhdGEgX3dhc18gYXZhaWxhYmxlIGZvciBhbGwgbGFrZXMgZnJvbSBwcmV2aW91c2x5IGNvbXBpbGVkIGdlb3NwYXRpYWwgZGF0YWJhc2VzLiBIb3dldmVyLCBuZWl0aGVyIHN1cmZhY2UgdGVtcGVyYXR1cmUgb3IgTk8zIHdlcmUgb2JzZXJ2ZWQgZm9yIGxha2VzIG91dHNpZGUgb2YgdGhlIHNhbXBsZS4gVGhleSB3ZXJlIHBhcnRpYWxseSBvYnNlcnZlZCB3aXRoIHJlc3BlY3QgdG8gdGhlIHRhcmdldCBwb3B1bGF0aW9uLiBUaGVpciBtaXNzaW5nbmVzcyBuZWVkZWQgdG8gYmUgYWNjb3VudGVkIGZvciBpbiBhIG1vZGVsLiBUaGVyZWZvcmUsIGEgbW9yZSBjb21wbGV4IG1vZGVsIHdhcyBjb25zdHJ1Y3RlZCBiZWxvdyB0aGF0IGluY2x1ZGVkIHN1cmZhY2UgdGVtcGVyYXR1cmUgYW5kIE5PMyBhcyBhZGRpdGlvbmFsIHJlc3BvbnNlcyBjb25kaXRpb25lZCBvbiB0aGUgc3VydmV5IGRlc2lnbiB2YXJpYWJsZXMgYW5kIGZ1bGx5IG9ic2VydmVkIGNvdmFyaWF0ZXMuIFRoaXMgYXBwcm9hY2ggdG8gaW5mZXJlbmNlIGZvciBOMk8gd2FzIHNpbWlsYXIgdG8gYSBCYXllc2lhbiBzdHJ1Y3R1cmFsIGVxdWF0aW9uIG1vZGVsIFtATWVya2xlX2V0YWxfMjAyMTsgQE1lcmtsZV9Sb3NzZWVsXzIwMThdLiBUaGUgbWFpbiBkZXRhaWxzIG9mIHRoZSBsb2dpY2FsIGRlcGVuZGVuY2Ugc3RydWN0dXJlIGNvdWxkIGJlIGNoYXJhY3Rlcml6ZWQgYXM6DQoNCiQkXGJlZ2lue2FsaWdufSANClxjb2xvcnsjMUY0NDlDfXtcYm9sZHN5bWJvbHtOXzJPX3tkaXNzfX19ICY9XHNpbSBTdXJ2ZXkgKyBBcmVhICsgXGNvbG9yeyNGMDUwMzl9e1xib2xkc3ltYm9se05PXzN9fSArIFxjb2xvcnsjRUVCQUI0fXtcYm9sZHN5bWJvbHtUZW1wfX0gXFwgDQpcY29sb3J7I0E4QjZDQ317XGJvbGRzeW1ib2x7Tl8yT197ZXF1aWx9fX0gJj1cc2ltIFN1cnZleSArIEVsZXYgICsgXGNvbG9yeyNFRUJBQjR9e1xib2xkc3ltYm9se1RlbXB9fVxcDQpcY29sb3J7I0YwNTAzOX17XGJvbGRzeW1ib2x7Tk9fM319ICY9XHNpbSBTdXJ2ZXkgKyBBcmVhICsgXGNvbG9yeyNFRUJBQjR9e1xib2xkc3ltYm9se1RlbXB9fSBcXCANClxjb2xvcnsjRUVCQUI0fXtcYm9sZHN5bWJvbHtUZW1wfX0gJj1cc2ltIFN1cnZleSArIExhdCArIEVsZXYgKyBEYXkNClxlbmR7YWxpZ259JCQNCg0KVmFyaWFibGVzIGluIGNvbG9yIHRleHQgYWJvdmUgd2VyZSB0cmVhdGVkIGFzIHBhcnRpYWxseSBvYnNlcnZlZCB3aXRoIHJlc3BlY3QgdG8gdGhlIHBvcHVsYXRpb24gb2YgaW50ZXJlc3QgKGkuZS4sIG9ic2VydmVkIG9ubHkgaW4gdGhlIHNhbXBsZSksIHdoZXJlYXMgdmFyaWFibGVzIGluIGJsYWNrIHRleHQgd2VyZSBjb25zaWRlcmVkIGZ1bGx5IG9ic2VydmVkLiBUaGUgcGFydGlhbGx5IG9ic2VydmVkIHZhcmlhYmxlcywgYmVpbmcgZGlzc29sdmVkIGFuZCBlcXVpbGlicml1bSBOMk8sIE5PMywgYW5kIHN1cmZhY2UgdGVtcGVyYXR1cmUsIHdlcmUgZWFjaCBtb2RlbGVkIGNvbmRpdGlvbmFsIG9uIHRoZSBzdXJ2ZXkgZGVzaWduIHZhcmlhYmxlcyBhbmQgb3RoZXIgcGFydGlhbGx5IGFuZC9vciBmdWxseSBvYnNlcnZlZCBjb3ZhcmlhdGVzLiBUaGlzIHN0cnVjdHVyYWwgZXF1YXRpb24gYXBwcm9hY2ggcmVxdWlyZXMgYSBtb3JlIGNvbXBsZXggc2V0IG9mIHBvc3QtcHJvY2Vzc2luZyBzdGVwcyBjb21wYXJlZCB0byBhIHR5cGljYWwgTVJQIGFuYWx5c2lzLiBJbiBvcmRlciB0byBwcm9wYWdhdGUgZXN0aW1hdGVzIGFuZCB1bmNlcnRhaW50eSB0aHJvdWdoIHRoZSBkZXBlbmRlbmN5IHN0cnVjdHVyZSBhbmQgbWFrZSBpbmZlcmVuY2VzLCB0aGUgZml0dGVkIG1vZGVsIHdhcyB1c2VkIHRvIGZpcnN0IHByZWRpY3Qgc3VyZmFjZSB0ZW1wZXJhdHVyZSBpbiB0aGUgdGFyZ2V0IHBvcHVsYXRpb24sIHNpbmNlIGl0IGRlcGVuZGVkIG9ubHkgb24gdGhlIGZ1bGx5IG9ic2VydmVkIGNvdmFyaWF0ZXMuIFRoYXQgcHJlZGljdGl2ZSBkaXN0cmlidXRpb24gd2FzIHRoZW4gdXNlZCBhbG9uZ3NpZGUgdGhlIHJlbGV2YW50IGZ1bGx5IG9ic2VydmVkIGNvdmFyaWF0ZXMgdG8gcHJlZGljdCBOTzMgaW4gdGhlIHRhcmdldCBwb3B1bGF0aW9uLiBGaW5hbGx5LCB0aGUgcHJlZGljdGl2ZSBkaXN0cmlidXRpb25zIGZvciB0ZXJtcGVyYXR1cmUgYW5kIE5PMyB3ZXJlIHVzZWQgdG8gcHJlZGljdCB0aGUgTjJPIHJlc3BvbnNlcy4gVGhlc2Ugc3RlcHMgd2VyZSBjYXJyaWVkIG91dCBpbiB0aGUgIlByZWRpY3QgdG8gcG9wdWxhdGlvbiIgc2VjdGlvbiB0byBmb2xsb3cuDQoNCkluIHRoZSBmaW5hbCBtb2RlbCBiZWxvdywgdGhlIHN1Ym1vZGVsIGZvciBzdXJmYWNlIHRlbXBlcmF0dXJlIGFzc3VtZWQgYSBHYW1tYSBkaXN0cmlidXRlZCBlcnJvciBkaXN0cmlidXRpb24gYW5kIHRoZSBsaW5lYXIgcHJlZGljdG9yIGluY2x1ZGVkIHRoZSBzdXJ2ZXkgZGVzaWduIHZhcmlhYmxlcywgbGF0aXR1ZGUsIGVsZXZhdGlvbiwgYW5kIGp1bGlhbiBkYXRlLiBUaGUgc2hhcGUgcGFyYW1ldGVyIHdhcyBhbHNvIG1vZGVsZWQgYXMgYSBmdW5jdGlvbiBvZiBsYXRpdHVkZSB0byBhZGRyZXNzIGluY3JlYXNpbmcgcmVzcG9uc2UgdmFyaWFuY2UgYWxvbmcgdGhlIGxhdGl0dWRpbmFsIGdyYWRpZW50LiBUaGUgTk8zIHN1Ym1vZGVsIHdhcyBhIGN1bXVsYXRpdmUgbG9naXQgZm9ybXVsYXRpb24gYW5kIHRoZSBsaW5lYXIgcHJlZGljdG9yIGluY2x1ZGVkIGFsbCBvZiB0aGUgc3VydmV5IGZhY3RvcnMgYXMgd2VsbCBhcyBzdXJmYWNlIHRlbXBlcmF0dXJlIGFuZCBsYWtlIGFyZWEuIA0KDQpUaGUgTjJPIGFuZCBOMk8tZXEgcmVzcG9uc2VzIHdlcmUgZWFjaCBtb2RlbGVkIHdpdGggR2FtbWEgZGlzdHJpYnV0ZWQgZXJyb3JzLCBidXQgd2l0aCB0aGUgc2FtZSBjb3ZhcmlhdGUgc3RydWN0dXJlIGFzIGluIG1vZGVsIDUuIFRoZSBzYW1lIHN0cnVjdHVyZSB3YXMgYWxzbyBlbXBsb3llZCBmb3IgdGhlIHNoYXBlIHRlcm1zIGluIHRoZXNlIHJlc3BvbnNlcywgY29ycmVzcG9uZGluZyB0byB0aGUgJFxzaWdtYSQgdGVybXMgaW4gdGhlIHByZXZpb3VzIG1vZGVsLiBUaG91Z2ggbm90IHNob3duIGluIHRoaXMgZG9jdW1lbnQsIHRoZSBHYW1tYSBlcnJvciBzdHJ1Y3R1cmUgYXBwZWFyZWQgdG8gcmVzdWx0IGluIHNsaWdodGx5IGJldHRlciBwZXJmb3JtYW5jZSBpbiB0aGUgcHJlZGljdGl2ZSBjaGVja3MgY29tcGFyZWQgdG8gdGhlIEdhdXNzaWFuIGVycm9ycyBpbiBwcmV2aW91cyBtb2RlbHMuIFRoaXMgd2FzIHByaW1hcmlseSBhcHBhcmVudCBpbiB0aGUgc2F0dXJhdGlvbiByYXRpbyBjaGVja3MsIHdoaWNoIG1heSBoYXZlIGJlZW4gbW9yZSBzZW5zaXRpdmUgdG8gbW9kZWwgcGVyZm9ybWFuY2UgaW4gdGhlIHRhaWxzIG9mIHRoZSBOMk8gcmVzcG9uc2VzLiBPdGhlcnMgaGF2ZSBhbHNvIGluZGljYXRlZCB0aGF0IHRoZSBHYW1tYSBlcnJvciBkaXN0cmlidXRpb24gY2FuIHdvcmsgd2VsbCBmb3IgZGlzc29sdmVkIE4yTyBkYXRhIFtAV2ViYl9ldGFsXzIwMTldLg0KDQpOb3RlIHRoYXQgdGhlcmUgd2FzIG5vIHJlc2lkdWFsIGNvcnJlbGF0aW9uIHRlcm0gZm9yIHRoaXMgbW9kZWwsIHNpbmNlIHRoZSByZXNpZHVhbHMgYXJlIHVuZGVmaW5lZCBmb3IgdGhlIEdhbW1hIGFuZCBjdW11bGF0aXZlIGxvZ2l0IG1vZGVscy4gRHJvcHBpbmcgdGhlIG9ic2VydmF0aW9uLWxldmVsIHJlc2lkdWFsIGNvcnJlbGF0aW9uIHRlcm0gd2FzIGRlZW1lZCBhIHJlYXNvbmFibGUgY29tcHJvbWlzZSB0aGF0IGVuYWJsZWQgbW9kZWxpbmcgdGhlIG1pc3NpbmduZXNzIG9mIE5PMywgaW4gcGFydGljdWxhci4gTmV2ZXJ0aGVsZXNzLCB0aGUgcmFuZG9tIGludGVyY2VwdHMgYWdhaW4gYWxsb3dlZCBmb3IgcG90ZW50aWFsIGNvcnJlbGF0aW9ucyBiZXR3ZWVuIHJlc3BvbnNlcyBhdCB0aGUgZ3JvdXAgbGV2ZWxzLiANCg0KYGBge3IgbjJvX21vZF9tdl82LCBldmFsPUZBTFNFLCBpbmNsdWRlPVRSVUV9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZl9tb2RlbC5yZGEiKQ0KDQpiZl9uMm8gPC0gYmYobjJvIH4gbW8obm8zX2NhdCkgKw0KICAgICAgICAgICAgICAgbG9nX2FyZWEgKw0KICAgICAgICAgICAgICAgc3VyZnRlbXAgKyANCiAgICAgICAgICAgICAgIG1vKG5vM19jYXQpOmxvZ19hcmVhICsNCiAgICAgICAgICAgICAgIG1vKG5vM19jYXQpOnN1cmZ0ZW1wICsNCiAgICAgICAgICAgICAgIChtbyhubzNfY2F0KSB8IGEgfCBXU0E5KSArIA0KICAgICAgICAgICAgICAgKG1vKG5vM19jYXQpIHwgYiB8IFdTQTk6c3RhdGUpICsgDQogICAgICAgICAgICAgICAoMSB8IGMgfCBXU0E5OnN0YXRlOnNpemVfY2F0KSwNCiAgICAgICAgICAgICBzaGFwZSB+IGxvZ19hcmVhICsNCiAgICAgICAgICAgICAgIG1vKG5vM19jYXQpICsNCiAgICAgICAgICAgICAgICgxIHwgV1NBOSkgKyANCiAgICAgICAgICAgICAgICgxIHwgV1NBOTpzdGF0ZSkgKyANCiAgICAgICAgICAgICAgICgxIHwgV1NBOTpzdGF0ZTpzaXplX2NhdCksDQogICAgICAgICAgICAgZmFtaWx5ID0gR2FtbWEobGluayA9ICJsb2ciKSkNCg0KYmZfbjJvZXEgPC0gYmYobjJvX2VxIH4gc3VyZnRlbXAgKw0KICAgICAgICAgICAgICAgICBsb2dfZWxldiArDQogICAgICAgICAgICAgICAgIHN1cmZ0ZW1wOmxvZ19lbGV2ICsNCiAgICAgICAgICAgICAgICAgKDEgfCBhIHwgV1NBOSkgKyANCiAgICAgICAgICAgICAgICAgKDEgfCBiIHwgV1NBOTpzdGF0ZSkgKw0KICAgICAgICAgICAgICAgICAoMSB8IGMgfCBXU0E5OnN0YXRlOnNpemVfY2F0KSwNCiAgICAgICAgICAgICBzaGFwZSB+IHN1cmZ0ZW1wICsNCiAgICAgICAgICAgICAgIGxvZ19lbGV2ICsNCiAgICAgICAgICAgICAgICgxIHwgV1NBOSkgKyANCiAgICAgICAgICAgICAgICgxIHwgV1NBOTpzdGF0ZSkgKyANCiAgICAgICAgICAgICAgICgxIHwgV1NBOTpzdGF0ZTpzaXplX2NhdCksDQogICAgICAgICAgICAgZmFtaWx5ID0gR2FtbWEobGluayA9ICJsb2ciKSkNCg0KYmZfdGVtcCA8LSBiZihzdXJmdGVtcCB+IGxhdCArDQogICAgICAgICAgICAgICAgcyhsb2dfZWxldikgKw0KICAgICAgICAgICAgICAgIHMoamRhdGUpICsNCiAgICAgICAgICAgICAgICAoMSB8IGEgfCBXU0E5KSArIA0KICAgICAgICAgICAgICAgICgxIHwgYiB8IFdTQTk6c3RhdGUpICsNCiAgICAgICAgICAgICAgICAoMSB8IGMgfCBXU0E5OnN0YXRlOnNpemVfY2F0KSwNCiAgICAgICAgICAgICAgc2hhcGUgfiBsYXQsDQogICAgICAgICAgICAgIGZhbWlseSA9IEdhbW1hKGxpbmsgPSAibG9nIikpDQoNCmJmX25vMyA8LSBiZihubzNfY2F0IH4gc3VyZnRlbXAgKw0KICAgICAgICAgICAgICAgbG9nX2FyZWEgKw0KICAgICAgICAgICAgICAgKDEgfCBhIHwgV1NBOSkgKw0KICAgICAgICAgICAgICAgKDEgfCBiIHwgV1NBOTpzdGF0ZSkgKw0KICAgICAgICAgICAgICAgKDEgfCBjIHwgV1NBOTpzdGF0ZTpzaXplX2NhdCksDQogICAgICAgICAgICAgZmFtaWx5ID0gY3VtdWxhdGl2ZShsaW5rID0gImxvZ2l0IiwgdGhyZXNob2xkPSJmbGV4aWJsZSIpKQ0KDQpwcmlvcnMgPC0gYygNCiAgcHJpb3Iobm9ybWFsKDIsIDEpLCBjbGFzcyA9ICJJbnRlcmNlcHQiLCByZXNwID0gIm4ybyIpLA0KICBwcmlvcihub3JtYWwoMCwgMSksIGNsYXNzID0gImIiLCByZXNwID0gIm4ybyIpLA0KICBwcmlvcihleHBvbmVudGlhbCgyKSwgY2xhc3MgPSAic2QiLCByZXNwID0gIm4ybyIpLA0KICBwcmlvcihub3JtYWwoNSwgNCksIGNsYXNzID0gIkludGVyY2VwdCIsIGRwYXIgPSAic2hhcGUiLCByZXNwID0gIm4ybyIpLA0KICBwcmlvcihub3JtYWwoMCwgMSksIGNsYXNzID0gImIiLCBkcGFyID0gInNoYXBlIiwgcmVzcCA9ICJuMm8iKSwNCiAgcHJpb3IoZXhwb25lbnRpYWwoMiksIGNsYXNzID0gInNkIiwgZHBhciA9ICJzaGFwZSIsIHJlc3AgPSAibjJvIiksDQogIA0KICBwcmlvcihub3JtYWwoMiwgMSksIGNsYXNzID0gIkludGVyY2VwdCIsIHJlc3AgPSAibjJvZXEiKSwgDQogIHByaW9yKG5vcm1hbCgwLCAxKSwgY2xhc3MgPSAiYiIsIHJlc3AgPSAibjJvZXEiKSwgIA0KICBwcmlvcihleHBvbmVudGlhbCgyKSwgY2xhc3MgPSAic2QiLCByZXNwID0gIm4yb2VxIiksDQogIHByaW9yKG5vcm1hbCg1LCA0KSwgY2xhc3MgPSAiSW50ZXJjZXB0IiwgZHBhciA9ICJzaGFwZSIsIHJlc3AgPSAibjJvZXEiKSwNCiAgcHJpb3Iobm9ybWFsKDAsIDEpLCBjbGFzcyA9ICJiIiwgZHBhciA9ICJzaGFwZSIsIHJlc3AgPSAibjJvZXEiKSwNCiAgcHJpb3IoZXhwb25lbnRpYWwoMiksIGNsYXNzID0gInNkIiwgZHBhciA9ICJzaGFwZSIsIHJlc3AgPSAibjJvZXEiKSwNCiAgDQogIHByaW9yKG5vcm1hbCgzLCAxKSwgY2xhc3MgPSAiSW50ZXJjZXB0IiwgcmVzcCA9ICJzdXJmdGVtcCIpLCANCiAgcHJpb3Iobm9ybWFsKDAsIDEpLCBjbGFzcyA9ICJiIiwgcmVzcCA9ICJzdXJmdGVtcCIpLCANCiAgcHJpb3IoZXhwb25lbnRpYWwoMC41KSwgY2xhc3MgPSAic2RzIiwgcmVzcCA9ICJzdXJmdGVtcCIpLA0KICBwcmlvcihleHBvbmVudGlhbCgyKSwgY2xhc3MgPSAic2QiLCByZXNwID0gInN1cmZ0ZW1wIiksDQogIHByaW9yKG5vcm1hbCg1LCA0KSwgY2xhc3MgPSAiSW50ZXJjZXB0IiwgZHBhciA9ICJzaGFwZSIsIHJlc3AgPSAic3VyZnRlbXAiKSwNCiAgcHJpb3Iobm9ybWFsKDAsIDEpLCBjbGFzcyA9ICJiIiwgZHBhciA9ICJzaGFwZSIsIHJlc3AgPSAic3VyZnRlbXAiKSwNCiAgDQogIHByaW9yKG5vcm1hbCgwLCAzKSwgY2xhc3MgPSAiSW50ZXJjZXB0IiwgcmVzcCA9ICJubzNjYXQiKSwNCiAgcHJpb3Iobm9ybWFsKDAsIDEpLCBjbGFzcyA9ICJiIiwgcmVzcCA9ICJubzNjYXQiKSwNCiAgcHJpb3IoZXhwb25lbnRpYWwoMSksIGNsYXNzID0gInNkIiwgcmVzcCA9ICJubzNjYXQiKSwNCiAgDQogIHByaW9yKGxraigyKSwgY2xhc3MgPSAiY29yIikNCiAgKQ0KDQpuMm9fbW9kNiA8LSBicm0oYmZfbjJvICsgDQogICAgICAgICAgICAgICAgICBiZl9uMm9lcSArIA0KICAgICAgICAgICAgICAgICAgYmZfdGVtcCArIA0KICAgICAgICAgICAgICAgICAgYmZfbm8zICsgDQogICAgICAgICAgICAgICAgICBzZXRfcmVzY29yKHJlc2NvciA9IEZBTFNFKSwNCiAgICAgICAgICAgICAgICBkYXRhID0gZGZfbW9kZWwsIA0KICAgICAgICAgICAgICAgIHByaW9yID0gcHJpb3JzLA0KICBjb250cm9sID0gbGlzdChhZGFwdF9kZWx0YSA9IDAuOTc1LCBtYXhfdHJlZWRlcHRoID0gMTQpLA0KICAjc2FtcGxlX3ByaW9yID0gIm9ubHkiLA0KICBzYXZlX3BhcnMgPSBzYXZlX3BhcnMoYWxsID0gVFJVRSksDQogIHNlZWQgPSA4NTEzMiwjMTQ1NDgsDQogICNpbml0ID0gbXlfaW5pdHMsDQogIGluaXRfciA9IDAuNSwNCiAgY2hhaW5zPTQsIA0KICBpdGVyPTUwMDAsIA0KICBjb3Jlcz00KQ0KDQpzYXZlKG4yb19tb2Q2LCBmaWxlID0gIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q2LnJkYSIpDQpgYGANCg0KIyMjIFN1bW1hcml6ZSBmaXQNCkJlbG93IGlzIGEgc3VtbWFyeSBvZiB0aGUgZml0dGVkIHBhcmFtZXRlcnMgYW5kIE1DTUMgZGlhZ25vc3RpY3MuIA0KYGBge3IgcHJpbnRfbW9kNiwgZWNobz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q2LnJkYSIpDQoNCnByaW50KG4yb19tb2Q2LCBkaWdpdHMgPSAzLCBwcmlvciA9IFQpDQpgYGANCg0KIyMjIE1vZGVsIGNoZWNrcw0KQmVsb3csIHRoZSBzYW1lIFBQQ3MgZm9yIE4yTyBhbmQgTjJPLWVxIHdlcmUgZW1wbG95ZWQgYXMgYmVmb3JlLg0KIyMjIyBOMk8gUFBDDQpUaGUgUFBDcyBmb3IgTjJPIGZyb20gdGhpcyBtb2RlbCB3ZXJlIHNpbWlsYXJseSByZWFzb25hYmxlIGFzIGZvciBtb2RlbHMgNCBhbmQgNSBhYm92ZS4NCmBgYHtyIHBwY19mdWxsX2NoZWNrc19tb2RfbjJvNiwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD04LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDYucmRhIikNCmdyaWQuYXJyYW5nZSgNCnBwX2NoZWNrKG4yb19tb2Q2LCANCiAgICAgICAgIHJlc3AgPSAibjJvIiwNCiAgICAgICAgIHR5cGUgPSAiZGVuc19vdmVybGF5IiwNCiAgICAgICAgIG5zYW1wbGVzID0gNDAsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgeGxhYihleHByZXNzaW9uKHBhc3RlKCJsb2coTiJbMl0sIk8pIGNvbmNlbnRyYXRpb24iKSkpICsgDQogIHlsYWIoImRlbnNpdHkiKQ0KLA0KcHBfY2hlY2sobjJvX21vZDYsIA0KICAgICAgICAgcmVzcCA9ICJuMm8iLA0KICAgICAgICAgdHlwZSA9ICJlY2RmX292ZXJsYXkiLA0KICAgICAgICAgbnNhbXBsZXMgPSA0MCwgDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgeGxhYihleHByZXNzaW9uKHBhc3RlKCJsb2coTiJbMl0sIk8pIGNvbmNlbnRyYXRpb24iKSkpICsgDQogIHlsYWIoImN1bXVsYXRpdmUgZGVuc2l0eSIpDQosDQpwcF9jaGVjayhuMm9fbW9kNiwgDQogICAgICAgICByZXNwID0gIm4ybyIsDQogICAgICAgICB0eXBlID0gInN0YXRfMmQiLCANCiAgICAgICAgIHN0YXQgPSBjKCJtZWFuIiwgInNkIiksIA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KcHBfY2hlY2sobjJvX21vZDYsIA0KICAgICAgICAgcmVzcCA9ICJuMm8iLA0KICAgICAgICAgdHlwZSA9ICJzdGF0XzJkIiwgDQogICAgICAgICBzdGF0ID0gYygia3VydG9zaXMiLCAic2tld25lc3MiKSwgDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpwcF9jaGVjayhuMm9fbW9kNiwgDQogICAgICAgICByZXNwID0gIm4ybyIsDQogICAgICAgICB0eXBlID0gInN0YXRfMmQiLCANCiAgICAgICAgIHN0YXQgPSBjKCJtaW4iLCAibWF4IiksIA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KcHBfY2hlY2sobjJvX21vZDYsIA0KICAgICAgICAgcmVzcCA9ICJuMm8iLA0KICAgICAgICAgdHlwZSA9ICJzY2F0dGVyX2F2ZyIsIA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLCBuY29sID0gMikNCmBgYA0KDQojIyMjIEVxdWlsaWJyaXVtIE4yTyBQUEMNCkFnYWluLCB0aGUgUFBDcyBmb3IgTjJPLWVxIGluIHRoaXMgbW9kZWwgd2VyZSBzaW1pbGFyIHRvIHRob3NlIGZvciBtb2RlbHMgNCBhbmQgNS4NCmBgYHtyIHBwY19mdWxsX2NoZWNrc19tb2RfbjJvZXE2LCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTgsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kNi5yZGEiKQ0KZ3JpZC5hcnJhbmdlKA0KcHBfY2hlY2sobjJvX21vZDYsIA0KICAgICAgICAgcmVzcCA9ICJuMm9lcSIsDQogICAgICAgICB0eXBlID0gImRlbnNfb3ZlcmxheSIsDQogICAgICAgICBuc2FtcGxlcyA9IDQwLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKSArDQogIHhsYWIoZXhwcmVzc2lvbihwYXN0ZSgibG9nKEVxdWlsaWJyaXVtIE4iWzJdLCJPKSBjb25jZW50cmF0aW9uIikpKSArIA0KICB5bGFiKCJkZW5zaXR5IikNCiwNCnBwX2NoZWNrKG4yb19tb2Q2LCANCiAgICAgICAgIHJlc3AgPSAibjJvZXEiLA0KICAgICAgICAgdHlwZSA9ICJlY2RmX292ZXJsYXkiLA0KICAgICAgICAgbnNhbXBsZXMgPSA0MCwgDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgeGxhYihleHByZXNzaW9uKHBhc3RlKCJsb2coRXF1aWxpYnJpdW0gTiJbMl0sIk8pIGNvbmNlbnRyYXRpb24iKSkpICsgDQogIHlsYWIoImN1bXVsYXRpdmUgZGVuc2l0eSIpDQosDQpwcF9jaGVjayhuMm9fbW9kNiwgDQogICAgICAgICByZXNwID0gIm4yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoIm1lYW4iLCAic2QiKSwgDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpwcF9jaGVjayhuMm9fbW9kNiwgDQogICAgICAgICByZXNwID0gIm4yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoImt1cnRvc2lzIiwgInNrZXduZXNzIiksIA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KcHBfY2hlY2sobjJvX21vZDYsIA0KICAgICAgICAgcmVzcCA9ICJuMm9lcSIsDQogICAgICAgICB0eXBlID0gInN0YXRfMmQiLCANCiAgICAgICAgIHN0YXQgPSBjKCJtaW4iLCAibWF4IiksIA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KcHBfY2hlY2sobjJvX21vZDYsIA0KICAgICAgICAgcmVzcCA9ICJuMm9lcSIsDQogICAgICAgICB0eXBlID0gInNjYXR0ZXJfYXZnIiwgDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosIG5jb2wgPSAyKQ0KYGBgDQoNCiMjIyMgQml2YXJpYXRlIFBQQw0KVGhpcyBtb2RlbCBhZ2FpbiBwcm92aWRlZCBhIHZlcnkgcmVhc29uYWJsZSByZXByZXNlbnRhdGlvbiBvZiB0aGUgYml2YXJpYXRlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIE4yTyBhbmQgTjJPLWVxIChiZWxvdykuDQpgYGB7ciBwcGNfYnZfY2hlY2tfbW9kX24ybzYsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q2LnJkYSIpDQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZl9tb2RlbC5yZGEiKQ0KZGZfbW9kZWwgJT4lDQogIGFkZF9wcmVkaWN0ZWRfZHJhd3MobjJvX21vZDYsDQogICAgICAgICAgICAgICAgICAgICAgcmVzcCA9IGMoIm4ybyIsIm4yb2VxIiksDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbG9nKG4yb19vYnMpLCB5ID0gbG9nKG4yb2VxX29icykpKSArDQogIGdlb21fZGVuc2l0eV8yZChhZXMoeCA9IGxvZyhuMm8pLCANCiAgICAgICAgICAgICAgICAgICAgICB5ID0gbG9nKG4yb2VxKSwgDQogICAgICAgICAgICAgICAgICAgICAgZ3JvdXAgPSAuZHJhdyksDQogICAgICAgICAgICAgICAgICBiaW5zID0gMTAsDQogICAgICAgICAgICAgICAgICBjb2xvciA9ICJsaWdodGJsdWUiLCANCiAgICAgICAgICAgICAgICAgIGFscGhhID0gMC40KSArDQogIGdlb21fZGVuc2l0eV8yZChjb2xvciA9ICJibGFjayIsIGJpbnMgPSAxMCkgKw0KICB4bGltKDEuMjUsIDIuNzUpICsNCiAgeWxpbSgxLjI1LCAyLjc1KSArDQogIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KYGBgDQoNCiMjIyMgU2F0dXJhdGlvbiBQUEMNClRoZSBzYXR1cmF0aW9uIHJhdGlvIFBQQ3MgYmVsb3cgc2hvdyBzaW1pbGFyIGJlaGF2aW9yIGFzIHdpdGggbW9kZWxzIDQgYW5kIDUgYWJvdmUsIGJ1dCB3aXRoIHBlcmhhcHMgc2xpZ2h0bHkgbGVzcyBiaWFzIGluIHRoZSBwcmVkaWN0aW9ucyBmb3IgdGhlIHByb3BvcnRpb24gb2YgdW5kZXJzYXR1cmF0ZWQgd2F0ZXJib2RpZXMgYW5kIGZld2VyIGV4dHJlbWUgcHJlZGljdGlvbnMgZm9yIHRoZSBtZWFucyBhbmQgc3RhbmRhcmQgZGV2aWF0aW9ucy4gVGhlIG9ic2VydmVkIF92cy5fIHByZWRpY3RlZCBQUEMgYWxzbyBhcHBlYXJzIHRvIGhhdmUgYSBiZXR0ZXIgYmVoYXZlZCB2YXJpYW5jZSBhbmQgbm8gZXh0cmVtZSBwcmVkaWN0aW9ucywgY29tcGFyZWQgdG8gbW9kZWxzIDQgYW5kIDUgd2l0aCB0aGUgbG9nbm9ybWFsIGVycm9ycy4NCmBgYHtyIHBwY19zYXRfY2hlY2tfbW9kX24ybzYsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q2LnJkYSIpDQpncmlkLmFycmFuZ2UoDQpkZl9tb2RlbCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kNiwgDQogICAgICAgICAgICAgICAgICAgICAgcmVzcCA9IGMoIm4ybyIsICJuMm9lcSIpLA0KICAgICAgICAgICAgICAgICAgICAgIG5kcmF3cyA9IDUwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIG11dGF0ZShzYXRfcmF0aW8gPSBuMm9fb2JzIC8gbjJvZXFfb2JzLA0KICAgICAgICAgc2F0X3ByZWQgPSBuMm8gLyBuMm9lcSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHNhdF9yYXRpbykpICsNCiAgZ2VvbV9kZW5zaXR5KGFlcyh4ID0gc2F0X3ByZWQsIGdyb3VwID0gLmRyYXcpLCANCiAgICAgICAgICAgICAgIG4gPSAxMDI0LCANCiAgICAgICAgICAgICAgIGFkanVzdCA9IDEsDQogICAgICAgICAgICAgICBjb2xvciA9ICJsaWdodGJsdWUiKSArDQogIGdlb21fZGVuc2l0eShuID0gMTAyNCwgYWRqdXN0ID0gMikgKw0KICB4bGltKDAsIDUpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCmRmX21vZGVsICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2Q2LCANCiAgICAgICAgICAgICAgICAgICAgICByZXNwID0gYygibjJvIiwgIm4yb2VxIiksIA0KICAgICAgICAgICAgICAgICAgICAgIG5kcmF3cyA9IDUwMCkgJT4lDQogIHJlbmFtZShuMm9fb2JzID0gbjJvLA0KICAgICAgICAgbjJvZXFfb2JzID0gbjJvX2VxKSAlPiUNCiAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAuY2F0ZWdvcnksDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gLnByZWRpY3Rpb24pICU+JQ0KICBtdXRhdGUodXNhdF9wcmVkID0gaWZlbHNlKG4ybyA8IG4yb2VxLCAxLCAwKSkgJT4lDQogIGdyb3VwX2J5KC5kcmF3KSAlPiUNCiAgc3VtbWFyaXNlKHByb3BfcHJlZCA9IHN1bSh1c2F0X3ByZWQpIC8gOTg0KSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gcHJvcF9wcmVkKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuMDAxLCBmaWxsID0gImxpZ2h0Ymx1ZSIpICsNCiAgZ2VvbV92bGluZShkYXRhID0gZGZfbW9kZWwsIG1hcHBpbmcgPSBhZXMoeGludGVyY2VwdCA9IHN1bShuMm8gPCBuMm9fZXEpLzk4NCkpICsNCiAgeGxhYigiUHJvcG9ydGlvbiB1bmRlcnNhdHVyYXRlZCB3YXRlcmJvZGllcyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCmRmX21vZGVsICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2Q2LCANCiAgICAgICAgICAgICAgICAgICAgICByZXNwID0gYygibjJvIiwgIm4yb2VxIiksIA0KICAgICAgICAgICAgICAgICAgICAgIG5kcmF3cyA9IDUwMCkgJT4lDQogIHJlbmFtZShuMm9fb2JzID0gbjJvLA0KICAgICAgICAgbjJvZXFfb2JzID0gbjJvX2VxKSAlPiUNCiAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAuY2F0ZWdvcnksDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gLnByZWRpY3Rpb24pICU+JQ0KICBtdXRhdGUoc2F0X3JhdGlvID0gbjJvX29icyAvIG4yb2VxX29icywNCiAgICAgICAgIHNhdF9wcmVkID0gbjJvIC8gbjJvZXEpICU+JQ0KICBncm91cF9ieSguZHJhdykgJT4lDQogIG11dGF0ZShtZWFuX3lyZXAgPSBtZWFuKHNhdF9wcmVkKSwNCiAgICAgICAgIHNkX3lyZXAgPSBzZChzYXRfcHJlZCkpICU+JSANCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUobWVhbl95ID0gbWVhbihzYXRfcmF0aW8pLA0KICAgICAgICAgc2RfeSA9IHNkKHNhdF9yYXRpbykpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBtZWFuX3lyZXAsIHkgPSBzZF95cmVwKSkgKw0KICBnZW9tX3BvaW50KGNvbG9yID0gImxpZ2h0Ymx1ZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdCA9IG1lYW5feSksIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IHNkX3kpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpkZl9tb2RlbCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kNiwgDQogICAgICAgICAgICAgICAgICAgICAgcmVzcCA9IGMoIm4ybyIsICJuMm9lcSIpLCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MDApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgbXV0YXRlKHNhdF9yYXRpbyA9IG4yb19vYnMgLyBuMm9lcV9vYnMsDQogICAgICAgICBzYXRfcHJlZCA9IG4ybyAvIG4yb2VxKSAlPiUNCiAgZ3JvdXBfYnkoLmRyYXcpICU+JQ0KICBtdXRhdGUobWluX3lyZXAgPSBtaW4oc2F0X3ByZWQpLA0KICAgICAgICAgbWF4X3lyZXAgPSBtYXgoc2F0X3ByZWQpKSAlPiUgDQogIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlKG1pbl95ID0gbWluKHNhdF9yYXRpbyksDQogICAgICAgICBtYXhfeSA9IG1heChzYXRfcmF0aW8pKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbWluX3lyZXAsIHkgPSBtYXhfeXJlcCkpICsNCiAgZ2VvbV9wb2ludChjb2xvciA9ICJsaWdodGJsdWUiKSArDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIGdlb21fdmxpbmUoYWVzKHhpbnRlcmNlcHQgPSBtaW5feSksIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IG1heF95KSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KZGZfbW9kZWwgJT4lDQogIGFkZF9wcmVkaWN0ZWRfZHJhd3MobjJvX21vZDYsIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSBjKCJuMm8iLCAibjJvZXEiKSwgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTAwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIG11dGF0ZShzYXRfcmF0aW8gPSBuMm9fb2JzIC8gbjJvZXFfb2JzLA0KICAgICAgICAgc2F0X3ByZWQgPSBuMm8gLyBuMm9lcSkgJT4lDQogIGdyb3VwX2J5KC5yb3cpICU+JQ0KICBtdXRhdGUobWVhbl95cmVwID0gbWVhbihzYXRfcHJlZCkpICU+JSANCiAgZmlsdGVyKC5kcmF3ID09IDEpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbWVhbl95cmVwLCB5ID0gc2F0X3JhdGlvKSkgKw0KICBnZW9tX3BvaW50KGNvbG9yID0gImxpZ2h0Ymx1ZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosIG5jb2wgPSAyKQ0KYGBgDQoNClRoZSBwbG90IGJlbG93IHNob3dzIHRoZSBzYW1lIFBQQywgYnV0IGZvciB0aGUgInRlc3QiIG9yIHNlY29uZC12aXN0IGRhdGEuIE92ZXJhbGwsIHRoZSBtb2RlbCBsb29rZWQgdG8gcGVyZm9ybSBzaW1pbGFybHkgYXMgd2l0aCB0aGUgZGF0YSB1c2VkIHRvIGZpdCBpdC4NCmBgYHtyIHBwY19zYXRfY2hlY2tfdGVzdGRhdGFfbW9kX24ybzYsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q2LnJkYSIpDQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZl90ZXN0LnJkYSIpDQpncmlkLmFycmFuZ2UoDQpkZl90ZXN0ICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2Q2LCANCiAgICAgICAgICAgICAgICAgICAgICByZXNwID0gYygibjJvIiwgIm4yb2VxIiksDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgbXV0YXRlKHNhdF9yYXRpbyA9IG4yb19vYnMgLyBuMm9lcV9vYnMsDQogICAgICAgICBzYXRfcHJlZCA9IG4ybyAvIG4yb2VxKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gc2F0X3JhdGlvKSkgKw0KICBnZW9tX2RlbnNpdHkoYWVzKHggPSBzYXRfcHJlZCwgZ3JvdXAgPSAuZHJhdyksIA0KICAgICAgICAgICAgICAgbiA9IDEwMjQsIA0KICAgICAgICAgICAgICAgYWRqdXN0ID0gMSwNCiAgICAgICAgICAgICAgIGNvbG9yID0gImxpZ2h0Ymx1ZSIpICsNCiAgZ2VvbV9kZW5zaXR5KG4gPSAxMDI0LCBhZGp1c3QgPSAyKSArDQogIHhsaW0oMCwgNSkgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KZGZfdGVzdCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kNiwgDQogICAgICAgICAgICAgICAgICAgICAgcmVzcCA9IGMoIm4ybyIsICJuMm9lcSIpLCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MDApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgbXV0YXRlKHVzYXRfcHJlZCA9IGlmZWxzZShuMm8gPCBuMm9lcSwgMSwgMCkpICU+JQ0KICBncm91cF9ieSguZHJhdykgJT4lDQogIHN1bW1hcmlzZShwcm9wX3ByZWQgPSBzdW0odXNhdF9wcmVkKSAvIDk1KSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gcHJvcF9wcmVkKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuMDAxLCBmaWxsID0gImxpZ2h0Ymx1ZSIpICsNCiAgZ2VvbV92bGluZShkYXRhID0gZGZfbW9kZWwsIG1hcHBpbmcgPSBhZXMoeGludGVyY2VwdCA9IHN1bShuMm8gPCBuMm9fZXEpLzk4NCkpICsNCiAgeGxhYigiUHJvcG9ydGlvbiB1bmRlcnNhdHVyYXRlZCB3YXRlcmJvZGllcyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCmRmX3Rlc3QgJT4lDQogIGFkZF9wcmVkaWN0ZWRfZHJhd3MobjJvX21vZDYsIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSBjKCJuMm8iLCAibjJvZXEiKSwgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTAwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIG11dGF0ZShzYXRfcmF0aW8gPSBuMm9fb2JzIC8gbjJvZXFfb2JzLA0KICAgICAgICAgc2F0X3ByZWQgPSBuMm8gLyBuMm9lcSkgJT4lDQogIGdyb3VwX2J5KC5kcmF3KSAlPiUNCiAgbXV0YXRlKG1lYW5feXJlcCA9IG1lYW4oc2F0X3ByZWQpLA0KICAgICAgICAgc2RfeXJlcCA9IHNkKHNhdF9wcmVkKSkgJT4lIA0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZShtZWFuX3kgPSBtZWFuKHNhdF9yYXRpbyksDQogICAgICAgICBzZF95ID0gc2Qoc2F0X3JhdGlvKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IG1lYW5feXJlcCwgeSA9IHNkX3lyZXApKSArDQogIGdlb21fcG9pbnQoY29sb3IgPSAibGlnaHRibHVlIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBnZW9tX3ZsaW5lKGFlcyh4aW50ZXJjZXB0ID0gbWVhbl95KSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICBnZW9tX2hsaW5lKGFlcyh5aW50ZXJjZXB0ID0gc2RfeSksIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCmRmX3Rlc3QgJT4lDQogIGFkZF9wcmVkaWN0ZWRfZHJhd3MobjJvX21vZDYsIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSBjKCJuMm8iLCAibjJvZXEiKSwgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTAwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIG11dGF0ZShzYXRfcmF0aW8gPSBuMm9fb2JzIC8gbjJvZXFfb2JzLA0KICAgICAgICAgc2F0X3ByZWQgPSBuMm8gLyBuMm9lcSkgJT4lDQogIGdyb3VwX2J5KC5kcmF3KSAlPiUNCiAgbXV0YXRlKG1pbl95cmVwID0gbWluKHNhdF9wcmVkKSwNCiAgICAgICAgIG1heF95cmVwID0gbWF4KHNhdF9wcmVkKSkgJT4lIA0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZShtaW5feSA9IG1pbihzYXRfcmF0aW8pLA0KICAgICAgICAgbWF4X3kgPSBtYXgoc2F0X3JhdGlvKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IG1pbl95cmVwLCB5ID0gbWF4X3lyZXApKSArDQogIGdlb21fcG9pbnQoY29sb3IgPSAibGlnaHRibHVlIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBnZW9tX3ZsaW5lKGFlcyh4aW50ZXJjZXB0ID0gbWluX3kpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIGdlb21faGxpbmUoYWVzKHlpbnRlcmNlcHQgPSBtYXhfeSksIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCmRmX3Rlc3QgJT4lDQogIGFkZF9wcmVkaWN0ZWRfZHJhd3MobjJvX21vZDYsIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSBjKCJuMm8iLCAibjJvZXEiKSwgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTAwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIG11dGF0ZShzYXRfcmF0aW8gPSBuMm9fb2JzIC8gbjJvZXFfb2JzLA0KICAgICAgICAgc2F0X3ByZWQgPSBuMm8gLyBuMm9lcSkgJT4lDQogIGdyb3VwX2J5KC5yb3cpICU+JQ0KICBtdXRhdGUobWVhbl95cmVwID0gbWVhbihzYXRfcHJlZCkpICU+JSANCiAgZmlsdGVyKC5kcmF3ID09IDEpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbWVhbl95cmVwLCB5ID0gc2F0X3JhdGlvKSkgKw0KICBnZW9tX3BvaW50KGNvbG9yID0gImxpZ2h0Ymx1ZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosIG5jb2wgPSAyKQ0KYGBgDQoNCiMjIyMgUi1zcXVhcmUNCkJlbG93IGFyZSBlc3RpbWF0ZXMgZm9yIHRoZSBCYXllc2lhbiAkUl4yJCwgd2hpY2ggd2VyZSBsYXJnZWx5IHNpbWlsYXIgZm9yIE4yTyBhbmQgTjJPLWVxIGFzIHdpdGggbW9kZWxzIDQgYW5kIDUgYWJvdmUuIFRoZSAkUl4yJCBmb3IgdGhlIHN1cmZhY2UgdGVtcGVyYXR1cmUgcmVzcG9uc2UgYWxzbyBzdWdnZXN0ZWQgYSBmYWlybHkgZ29vZCBmaXQuDQpgYGB7ciByMl9tb2RfbjJvNiwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NCwgZmlnLmhlaWdodD00fQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDYucmRhIikNCnJvdW5kKGJheWVzX1IyKG4yb19tb2Q2LCByZXNwID0gIm4ybyIpLCAzKSANCnJvdW5kKGJheWVzX1IyKG4yb19tb2Q2LCByZXNwID0gIm4yb2VxIiksIDMpDQpyb3VuZChiYXllc19SMihuMm9fbW9kNiwgcmVzcCA9ICJzdXJmdGVtcCIpLCAzKQ0KYGBgDQoNCkJlbG93IGFyZSB0aGUgc2FtZSAkUl4yJCBlc3RpbWF0ZXMsIGJ1dCBmb3IgdGhlIHNlY29uZC12aXNpdCBkYXRhLiBUaGF0IHRoZXNlIGVzdGltYXRlcyBhcmUgc2ltaWxhciB0byB0aG9zZSBmb3IgdGhlIGRhdGEgdXNlZCB0byBmaXQgdGhlIG1vZGVsLCBzdWdnZXN0aW5nIHRoYXQgdGhlIG1vZGVsIG1heSBwZXJmb3JtIHNpbWlsYXJseSB3ZWxsIG91dC1vZi1zYW1wbGUuDQpgYGB7ciByMl90ZXN0X21vZF9uMm82LCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD00LCBmaWcuaGVpZ2h0PTR9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kNi5yZGEiKQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvZGZfdGVzdC5yZGEiKQ0Kcm91bmQoYmF5ZXNfUjIobjJvX21vZDYsIHJlc3AgPSAibjJvIiwgbmV3ZGF0YSA9IGRmX3Rlc3QpLCAzKSANCnJvdW5kKGJheWVzX1IyKG4yb19tb2Q2LCByZXNwID0gIm4yb2VxIiwgbmV3ZGF0YSA9IGRmX3Rlc3QpLCAzKQ0Kcm91bmQoYmF5ZXNfUjIobjJvX21vZDYsIHJlc3AgPSAic3VyZnRlbXAiLCBuZXdkYXRhID0gZGZfdGVzdCksIDMpDQpgYGANCg0KIyMjIENvdmFyaWF0ZSBlZmZlY3RzDQojIyMjIE4yTw0KVGhlIGNvbmRpdGlvbmFsIGVmZmVjdHMgcGxvdCBmb3IgdGhlIGNvdmFyaWF0ZSBlZmZlY3RzIE4yTyBzdWdnZXN0ZWQgYSBzaW1pbGFyIGVmZmVjdCBvZiBOTzMsIGJ1dCBpbnRlcmVzdGluZyBpbnRlcmFjdGlvbnMgYmV0d2VlbiBOTzMgYW5kIGxha2UgYXJlYSBhbmQgTk8zIGFuZCBzdXJmYWNlIHRlbXBlcmF0dXJlLiBGb3IgbGFrZSBhcmVhLCB0aGUgZWZmZWN0IHdhcyBlc3RpbWF0ZWQgdG8gYmUgbGFyZ2VyIGFuZCBtb3JlIG5lZ2F0aXZlIGF0IHRoZSBoaWdoZXN0IGxldmVscyBvZiBOTzM7IGFuZCBzbGlnaHRseSBuZWdhdGl2ZSBhdCB0aGUgbG93ZXN0IGxldmVsIG9mIE5PMy4gRm9yIHN1cmZhY2UgdGVtcGVyYXR1cmUsIHRoZSBlZmZlY3Qgd2FzIGVzdGltYXRlZCB0byBiZSBsYXJnZXN0IGFuZCBwb3NpdGl2ZSBhdCB0aGUgaGlnaGVzdCBsZXZlbCBvZiBOTzM7IGFuZCBuZWdhdGl2ZSBhdCB0aGUgbG93ZXN0IGxldmVsIG9mIE5PMy4NCmBgYHtyIGNvbmRpdGlvbmFsX2VmZmVjdHNfbW9kX24yb0YsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9NH0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q2LnJkYSIpDQoNCnAxIDwtIGNvbmRpdGlvbmFsX2VmZmVjdHMobjJvX21vZDYsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwID0gIm4ybyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBlZmZlY3RzID0gYygibm8zX2NhdCIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcGxvdCA9IEYpDQoNCnAyIDwtIGNvbmRpdGlvbmFsX2VmZmVjdHMobjJvX21vZDYsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwID0gIm4ybyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBlZmZlY3RzID0gYygibG9nX2FyZWE6bm8zX2NhdCIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcGxvdCA9IEYpDQpwMyA8LSBjb25kaXRpb25hbF9lZmZlY3RzKG4yb19tb2Q2LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcCA9ICJuMm8iLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgZWZmZWN0cyA9IGMoInN1cmZ0ZW1wOm5vM19jYXQiKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHBsb3QgPSBGKQ0KDQpwbHQgPC0gZ2dhcnJhbmdlKHBsb3QocDEsIHBsb3QgPSBGKVtbMV1dLCANCiAgICAgICAgICAgICAgICAgcGxvdChwMiwgcGxvdCA9IEYpW1sxXV0sDQogICAgICAgICAgICAgICAgIHBsb3QocDMsIHBsb3QgPSBGKVtbMV1dKQ0KDQpybShwMSwgcDIsIHAzKQ0KDQphbm5vdGF0ZV9maWd1cmUocGx0LCB0b3AgPSB0ZXh0X2dyb2IoZXhwcmVzc2lvbihwYXN0ZSgiTjJPOiBjb3ZhcmlhdGUgZWZmZWN0cyBvbiAiLCBtdSkpLCANCiAgICAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIiwgZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE0KSkNCmBgYA0KDQpUaGUgZXN0aW1hdGVkIGNvdmFyaWF0ZSBlZmZlY3RzIG9uICRcc2lnbWEkIHN1Z2dlc3RlZCBhIG5lZ2F0aXZlIHJlbGF0aW9uc2hpcCB3aXRoIGxvZyhhcmVhKSBhbmQgYSBwb3NpdGl2ZSByZWxhdGlvbnNoaXAsIGFnYWluLCB3aXRoIE5PMy4NCmBgYHtyIGNvbmRpdGlvbmFsX2VmZmVjdHNfc2lnbWFfbjJvRiwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD0yfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDYucmRhIikNCg0KcDEgPC0gY29uZGl0aW9uYWxfZWZmZWN0cyhuMm9fbW9kNiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSAibjJvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgZHBhciA9ICJzaGFwZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGVmZmVjdHMgPSBjKCJsb2dfYXJlYSIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90ID0gRikNCg0KcDIgPC0gY29uZGl0aW9uYWxfZWZmZWN0cyhuMm9fbW9kNiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSAibjJvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgZHBhciA9ICJzaGFwZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGVmZmVjdHMgPSBjKCJubzNfY2F0IiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90ID0gRikNCg0KcGx0IDwtIGdnYXJyYW5nZShwbG90KHAxLCBwbG90ID0gRilbWzFdXSwNCiAgICAgICAgICAgICAgICAgcGxvdChwMiwgcGxvdCA9IEYpW1sxXV0pDQoNCnJtKHAxLCBwMikNCg0KYW5ub3RhdGVfZmlndXJlKHBsdCwgDQogICAgICAgICAgICAgICAgdG9wID0gdGV4dF9ncm9iKGV4cHJlc3Npb24ocGFzdGUoIk4yTzogY292YXJpYXRlIGVmZmVjdHMgb24gIiwgc2hhcGUpKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWNlID0gImJvbGQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplID0gMTQpKQ0KYGBgDQoNCiMjIyMgRXF1aWxpYnJpdW0gTjJPDQpUaGUgZXN0aW1hdGVkIGNvdmFyaWF0ZSBlZmZlY3Qgb24gTjJPIHJlbWFpbmVkIGxhcmdlbHkgdGhlIHNhbWUgYXMgZXN0aW1hdGVkIGluIHRoZSBwcmV2aW91cyBtb2RlbC4NCmBgYHtyIGNvbmRpdGlvbmFsX2VmZmVjdHNfbW9kX24yb2VxRiwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD0yfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDYucmRhIikNCg0KcDEgPC0gY29uZGl0aW9uYWxfZWZmZWN0cyhuMm9fbW9kNiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSAibjJvZXEiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgZWZmZWN0cyA9IGMoInN1cmZ0ZW1wOmxvZ19lbGV2IiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90ID0gRikNCg0KcDIgPC0gY29uZGl0aW9uYWxfZWZmZWN0cyhuMm9fbW9kNiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSAibjJvZXEiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgZWZmZWN0cyA9IGMoImxvZ19lbGV2OnN1cmZ0ZW1wIiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90ID0gRikNCg0KcGx0IDwtIGdnYXJyYW5nZShwbG90KHAxLCBwbG90ID0gRilbWzFdXSwNCiAgICAgICAgICAgICAgICAgcGxvdChwMiwgcGxvdCA9IEYpW1sxXV0pDQoNCnJtKHAxLCBwMikNCg0KYW5ub3RhdGVfZmlndXJlKHBsdCwgdG9wID0gdGV4dF9ncm9iKGV4cHJlc3Npb24ocGFzdGUoIkVxdWlsaWJyaXVtIE4yTzogY292YXJpYXRlIGVmZmVjdHMgb24gIiwgbXUpKSwgDQogICAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIsIGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNCkpDQpgYGANCg0KYGBge3IgY29uZGl0aW9uYWxfZWZmZWN0c19zaWdtYV9uMm9lcUYsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Mn0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q2LnJkYSIpDQoNCnAxIDwtIGNvbmRpdGlvbmFsX2VmZmVjdHMobjJvX21vZDYsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwID0gIm4yb2VxIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgZHBhciA9ICJzaGFwZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGVmZmVjdHMgPSBjKCJzdXJmdGVtcCIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcGxvdCA9IEYpDQoNCnAyIDwtIGNvbmRpdGlvbmFsX2VmZmVjdHMobjJvX21vZDYsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwID0gIm4yb2VxIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgZHBhciA9ICJzaGFwZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGVmZmVjdHMgPSBjKCJsb2dfZWxldiIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcGxvdCA9IEYpDQoNCnBsdCA8LSBnZ2FycmFuZ2UocGxvdChwMSwgcGxvdCA9IEYpW1sxXV0sDQogICAgICAgICAgICAgICAgIHBsb3QocDIsIHBsb3QgPSBGKVtbMV1dKQ0KDQpybShwMSwgcDIpDQoNCmFubm90YXRlX2ZpZ3VyZShwbHQsIHRvcCA9IHRleHRfZ3JvYihleHByZXNzaW9uKHBhc3RlKCJFcXVpbGlicml1bSBOMk86IGNvdmFyaWF0ZSBlZmZlY3RzIG9uICIsIHNoYXBlKSksIA0KICAgICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siLCBmYWNlID0gImJvbGQiLCBzaXplID0gMTQpKQ0KYGBgDQoNCiMgUHJlZGljdCB0byBwb3B1bGF0aW9uDQpBcyBwcmV2aW91c2x5IGRlc2NyaWJlZCwgaW4gb3JkZXIgdG8gbWFrZSBpbmZlcmVuY2VzIHRvIHRoZSBwb3B1bGF0aW9uIG9mIGludGVyZXN0LCB0aGUgZmluYWwgbW9kZWwgYWJvdmUgd2FzIHVzZWQgdG8sIGZpcnN0LCBwcmVkaWN0IHN1cmZhY2UgdGVtcGVyYXR1cmUgaW4gdGhlIHRhcmdldCBwb3B1bGF0aW9uLCBzaW5jZSBpdCBkZXBlbmRlZCBvbmx5IG9uIHRoZSBmdWxseSBvYnNlcnZlZCBjb3ZhcmlhdGVzLiBOZXh0LCB0aGUgcHJlZGljdGl2ZSBkaXN0cmlidXRpb24gZm9yIHN1cmZhY2UgdGVtcGVyYXR1cmUgd2FzIHVzZWQsIGFsb25nIHdpdGggdGhlIHJlbGV2YW50IGZ1bGx5IG9ic2VydmVkIGNvdmFyaWF0ZXMsIHRvIHByZWRpY3QgTk8zIGluIHRoZSB0YXJnZXQgcG9wdWxhdGlvbi4gRmluYWxseSwgdGhlIHByZWRpY3RpdmUgZGlzdHJpYnV0aW9ucyBmb3IgdGVtcGVyYXR1cmUgYW5kIE5PMyB3ZXJlIHVzZWQgdG8gcHJlZGljdCB0aGUgTjJPIHJlc3BvbnNlcy4gVGhlIGNvZGUgZm9yIHRoZXNlIHN0ZXBzIGlzIG91dGxpbmVkIGluIHRoZSBmb2xsb3dpbmcuDQoNClRoZSBmaXJzdCBzdGVwIHVzZWQgdGhlIGZpbmFsIG1vZGVsIHRvIHByZWRpY3QgdG8gdGhlIHBvcHVsYXRpb246DQpgYGB7ciBwcmVkaWN0X29ic2ZyYW1lLCBldmFsPUZBTFNFLCBpbmNsdWRlPVRSVUV9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9zZnJhbWUucmRhIikNCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q2LnJkYSIpDQoNCnByZWRpY3RfdGVtcCA8LSBzZnJhbWUgJT4lDQogIG11dGF0ZShqZGF0ZSA9IDIwNSkgJT4lDQogIGFkZF9wcmVkaWN0ZWRfZHJhd3MobjJvX21vZDYsIHJlc3A9Yygic3VyZnRlbXAiKSwgDQogICAgICAgICAgICAgICAgICAgICAgYWxsb3dfbmV3X2xldmVscyA9IFRSVUUsIA0KICAgICAgICAgICAgICAgICAgICAgIGNvcmVzID0xLCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MDApICU+JQ0KICBtdXRhdGUoc3VyZnRlbXAgPSAucHJlZGljdGlvbikNCg0Kc2F2ZShwcmVkaWN0X3RlbXAsIGZpbGUgPSAiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvcHJlZGljdF90ZW1wLnJkYSIpDQpgYGANCg0KTk8zIHdhcyBuZXh0IHByZWRpY3RlZC4gTm90ZSB0aGF0IHRoZSBwb3N0ZXJpb3IgcHJlZGljdGl2ZSBkaXN0cmlidXRpb24gZm9yIE5PMyB3YXMgc3Vic2FtcGxlZCBpbiBvcmRlciB0byBtaW5pbWl6ZSBleGNlc3Mgc2ltdWxhdGlvbnMNCmBgYHtyIHBhcmFsbGVsX3ByZWRpY3RfZHJhd3MsIGV2YWw9RkFMU0UsIGluY2x1ZGU9VFJVRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q2LnJkYSIpDQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9wcmVkaWN0X3RlbXAucmRhIikNCg0KdGVtcF9YIDwtIHByZWRpY3RfdGVtcCAlPiUgIyBzZWxlY3QgcmVsZXZhbnQgY29sdW1ucyBhcyBwcmVkaWN0b3JzDQogIHVuZ3JvdXAoKSAlPiUNCiAgc2VsZWN0KFdTQTksDQogICAgICAgICBzdGF0ZSwNCiAgICAgICAgIHNpemVfY2F0LA0KICAgICAgICAgbG9nX2FyZWEsDQogICAgICAgICAucm93LA0KICAgICAgICAgLmRyYXcsDQogICAgICAgICBzdXJmdGVtcCkgJT4lDQogIHNlbGVjdChXU0E5LCBzdGF0ZSwgc2l6ZV9jYXQsIGxvZ19hcmVhLCBzdXJmdGVtcCkNCg0KDQpybShwcmVkaWN0X3RlbXApICMgcmVkdWNlIG1lbW9yeQ0KZ2MoKQ0KDQojIHNldCBudW1iZXIgb2YgY29yZXMgdG8gdXNlIGZvciBwYXJhbGxlbCBwcmVkaWN0aW9ucw0KIyBhbmQgcmVnaXN0ZXIgdGhlIHdvcmtlcnMNCmNsIDwtIHBhcmFsbGVsOjptYWtlQ2x1c3Rlcig1KSANCmRvU05PVzo6cmVnaXN0ZXJEb1NOT1coY2wpIA0KDQojIG1ha2UgYSBwcm9ncmVzcyBiYXINCnBiIDwtIHR4dFByb2dyZXNzQmFyKG1heCA9IDE1MDAsIHN0eWxlID0gMykNCnByb2dyZXNzIDwtIGZ1bmN0aW9uKG4pIHNldFR4dFByb2dyZXNzQmFyKHBiLCBuKQ0Kb3B0cyA8LSBsaXN0KHByb2dyZXNzID0gcHJvZ3Jlc3MpDQoNCnN5c3RlbS50aW1lKCAjIGFwcHJveCAyNiBocnMgd2l0aCA1IHdvcmtlcnMgJiA1MDAgZHJhd3MgZnJvbSBQUEQNCnByZWRpY3Rfbm8zIDwtIGZvcmVhY2goc3ViX1ggPSBpc3BsaXRSb3dzKHRlbXBfWCwgY2h1bmtTaXplID0gMTU1Mjk5KSwgDQogICAgICAgICAgICAgICAgICAgICAgIC5jb21iaW5lID0gJ2MnLA0KICAgICAgICAgICAgICAgICAgICAgICAucGFja2FnZXMgPSBjKCJicm1zIiksDQogICAgICAgICAgICAgICAgICAgICAgIC5vcHRpb25zLnNub3cgPSBvcHRzDQogICAgICAgICAgICAgICAgICAgICAgICkgJWRvcGFyJSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgYXBwbHkoYnJtczo6cG9zdGVyaW9yX3ByZWRpY3QobjJvX21vZDYsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3ZGF0YSA9IHN1Yl9YLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSAibm8zY2F0IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGxvd19uZXdfbGV2ZWxzID0gVCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MDAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29yZXMgPSAxKSwgMiwgc2FtcGxlLCAxKQ0KICAgICAgICAgICAgICAgICAgICAgICAgIH0NCikNCg0KDQpjbG9zZShwYikNCnBhcmFsbGVsOjpzdG9wQ2x1c3RlcihjbCkNCg0Kc2F2ZShwcmVkaWN0X25vMywgZmlsZSA9ICJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9wcmVkaWN0X25vMy5yZGEiKQ0KYGBgDQoNCkZpbmFsbHksIE4yTyBhbmQgTjJPLWVxIHdlcmUgcHJlZGljdGVkIHVzaW5nIHRoZSBzdXJmYWNlIHRlbXBlcmF0dXJlIGFuZCBuaXRyYXRlIHByZWRpY3Rpb25zIGFsb25nIHdpdGggdGhlIHN1cnZleSB2YXJpYWJsZXMgYW5kIGtub3duIGNvdmFyaWF0ZXMuIEFnYWluLCB0aGUgcG9zdGVyaW9yIHdhcyBzdWJzYW1wbGVkIGluIG9yZGVyIHRvIHJlZHVjZSBleGNlc3Mgc2ltdWxhdGlvbnMuDQpgYGB7ciBuMm9fY292YXJpYXRlc19YLCBldmFsPUZBTFNFLCBpbmNsdWRlPVRSVUV9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9wcmVkaWN0X25vMy5yZGEiKQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvcHJlZGljdF90ZW1wLnJkYSIpDQoNCiMgQXNzZW1ibGUgZGF0YWZyYW1lIGNvbnRhaW5pbmcgcmVsZXZhbnQgY292YXJpYXRlcyAoa25vd24gYW5kIHByZWRpY3RlZCkNCm4yb19YIDwtIHByZWRpY3RfdGVtcCAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUobm8zX2NhdCA9IHByZWRpY3Rfbm8zKSAlPiUNCiAgc2VsZWN0KFdTQTksDQogICAgICAgICBzdGF0ZSwNCiAgICAgICAgIHNpemVfY2F0LA0KICAgICAgICAgbG9nX2FyZWEsDQogICAgICAgICBzdXJmdGVtcCwNCiAgICAgICAgIGxvZ19lbGV2LA0KICAgICAgICAgbm8zX2NhdCkNCg0KIyBjbGVhciBvYmplY3RzIHRvIHJlZHVjZSBtZW1vcnkgb3ZlcmhlYWQNCnJtKHByZWRpY3Rfbm8zLCBwcmVkaWN0X3RlbXApIA0KZ2MoKQ0KDQojIHNhdmUgdGhlIHByZWRpY3RvcnMgZm9yIG4ybyBhbmQgbjJvZXENCnNhdmUobjJvX1gsIGZpbGUgPSAiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX1gucmRhIikNCmBgYA0KDQpgYGB7ciBwYXJhbGxlbF9wcmVkaWN0LCBldmFsPUZBTFNFLCBpbmNsdWRlPVRSVUV9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kNi5yZGEiKQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX1gucmRhIikNCg0KIyBzZXQgbnVtYmVyIG9mIGNvcmVzIHRvIHVzZSBmb3IgcGFyYWxsZWwgcHJlZGljdGlvbnMNCiMgYW5kIHJlZ2lzdGVyIHRoZSB3b3JrZXJzDQpjbCA8LSBwYXJhbGxlbDo6bWFrZUNsdXN0ZXIoNikgDQpkb1NOT1c6OnJlZ2lzdGVyRG9TTk9XKGNsKSANCg0KIyBtYWtlIGEgcHJvZ3Jlc3MgYmFyDQpwYiA8LSB0eHRQcm9ncmVzc0JhcihtYXggPSAxNTAwLCBzdHlsZSA9IDMpDQpwcm9ncmVzcyA8LSBmdW5jdGlvbihuKSBzZXRUeHRQcm9ncmVzc0JhcihwYiwgbikNCm9wdHMgPC0gbGlzdChwcm9ncmVzcyA9IHByb2dyZXNzKQ0KDQojIG1ha2UgcHJlZGljdGlvbnMgaW4gcGFyYWxsZWwNCnN5c3RlbS50aW1lKA0KcHJlZGljdF9uMm8gPC0gZm9yZWFjaChzdWJfWCA9IGlzcGxpdFJvd3MobjJvX1gsIGNodW5rU2l6ZSA9IDE1NTI5OSksDQogICAgICAgICAgICAgICAgIC5jb21iaW5lID0gcmJpbmQsDQogICAgICAgICAgICAgICAgIC5vcHRpb25zLnNub3cgPSBvcHRzLA0KICAgICAgICAgICAgICAgICAucGFja2FnZXMgPSBjKCJicm1zIikpICVkb3BhciUgew0KICBhcHBseShwb3N0ZXJpb3JfcHJlZGljdChuMm9fbW9kNiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3ZGF0YSA9IHN1Yl9YLA0KICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwID0gYygibjJvIiwgIm4yb2VxIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgIGFsbG93X25ld19sZXZlbHMgPSBULA0KICAgICAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MDAsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGNvcmVzID0gMSksDQogICAgICAgIDIsIHNhbXBsZSwgMSkNCiAgICAgICAgICAgICAgICAgICB9DQopDQoNCmNsb3NlKHBiKQ0KcGFyYWxsZWw6OnN0b3BDbHVzdGVyKGNsKQ0KDQpjb2xuYW1lcyhwcmVkaWN0X24ybykgPC0gYygibjJvIiwgIm4yb2VxIikNCg0Kc2F2ZShwcmVkaWN0X24ybywgZmlsZSA9ICJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9wcmVkaWN0X24yby5yZGEiKQ0KYGBgDQoNCkZpbmFsbHksIHRoZSBwcmVkaWN0aW9ucyBmb3IgYWxsIGZvdXIgcGFydGlhbGx5IG9ic2VydmVkIHJlc3BvbnNlcyB3ZXJlIGFzc2VtYmxlZCBpbnRvIGEgbmV3IGRhdGFmcmFtZSBmb3IgdXNlIGluIGluZmVyZW5jZS4NCmBgYHtyIGFzc2VtYmxlX3ByZWRpY3Rpb25zLCBldmFsPUZBTFNFLCBpbmNsdWRlPVRSVUV9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9wcmVkaWN0X24yby5yZGEiKQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvcHJlZGljdF9ubzMucmRhIikNCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL3ByZWRpY3RfdGVtcC5yZGEiKQ0KDQphbGxfcHJlZGljdGlvbnMgPC0gcHJlZGljdF90ZW1wICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZShubzNjYXQgPSBwcmVkaWN0X25vMykgJT4lDQogIGJpbmRfY29scyhwcmVkaWN0X24ybykgJT4lDQogIG11dGF0ZShuMm9zYXQgPSBuMm8gLyBuMm9lcSwgIyBjYWxjdWxhdGUgc2F0dXJhdGlvbiByYXRpbw0KICAgICAgICAgLnJvdyA9IHJlcCgxOjQ2NTg5NywgZWFjaCA9IDUwMCksDQogICAgICAgICAuZHJhdyA9IHJlcChzZXEoMSw1MDAsIDEpLCA0NjU4OTcpKSAlPiUNCiAgbXV0YXRlKGFyZWFfaGEgPSBleHAobG9nX2FyZWEpKSAlPiUgIyBpbmNsdWRlIGFyZWEgb24gaGEgc2NhbGUNCiAgc2VsZWN0KFdTQTksDQogICAgICAgICBzdGF0ZSwNCiAgICAgICAgIHNpemVfY2F0LA0KICAgICAgICAgYXJlYV9oYSwNCiAgICAgICAgIGxhdCwNCiAgICAgICAgIGxvbiwNCiAgICAgICAgIC5yb3csDQogICAgICAgICAuZHJhdywNCiAgICAgICAgIHN1cmZ0ZW1wLA0KICAgICAgICAgbm8zY2F0LA0KICAgICAgICAgbjJvLA0KICAgICAgICAgbjJvZXEsDQogICAgICAgICBuMm9zYXQpDQoNCnJtKHByZWRpY3RfbjJvLCBwcmVkaWN0X3RlbXAsIHByZWRpY3Rfbm8zKSAjIGNsZWFuIHVwIHdvcmtzcGFjZSBmb3IgUkFNDQpnYygpDQogDQoNCnNhdmUoYWxsX3ByZWRpY3Rpb25zLCBmaWxlID0gIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2FsbF9wcmVkaWN0aW9ucy5yZGEiKQ0KYGBgDQoNCiMgUG9wdWxhdGlvbiBlc3RpbWF0ZXMNCkEgbnVtYmVyIG9mIGVzdGltYXRlcyBmb3IgdGhlIHRhcmdldCBwb3B1bGF0aW9uIHdlcmUgYXNzZW1ibGVkIGFuZCBwcmVzZW50ZWQgYmVsb3cuIEZpcnN0LCB0aGUgZnVsbCBwb3N0ZXJpb3IgcHJlZGljdGl2ZSBkaXN0cmlidXRpb25zIGZvciBkaXNzb2x2ZWQgTjJPLCBlcXVpbGlicml1bSBOMm8sIGFuZCB0aGUgc2F0dXJhdGlvbiByYXRpbyB3ZXJlIGFzc2Vzc2VkLiBUaGVzZSBkaXN0cmlidXRpb25zIHN1bW1hcml6ZWQgdGhlIHByZWRpY3RlZCBkaXN0cmlidXRpb24gb2YgY29uY2VudHJhdGlvbnMgb3IgcmF0aW9zIGZvciBhbGwgbGFrZXMgaW4gdGhlIHBvcHVsYXRpb24gb2YgaW50ZXJlc3QgYW5kIGluY2x1ZGVkIHBhcmFtZXRlciB1bmNlcnRhaW50eSBwcm9wYWdhdGVkIHRocm91Z2ggdGhlIG1vZGVsLiBOZXh0LCBwb3B1bGF0aW9uIG1lYW5zIHdlcmUgYXNzZXNzZWQsIGZvbGxvd2VkIGJ5IGNvbXBhcmlzb25zIG9mIHNvbWUgbW9kZWwtYmFzZWQgZXN0aW1hdGVzIHRvIHByZXZpb3VzbHkgY2FsY3VsYXRlZCBkZXNpZ24tYmFzZWQgZXN0aW1hdGVzLg0KDQojIyBQb3N0ZXJpb3IgcHJlZGljdGl2ZSBkaXN0cmlidXRpb25zDQpCZWxvdywgYSBkZW5zaXR5IHBsb3Qgc3VtbWFyaXplZCB0aGUgcG9zdGVyaW9yIHByZWRpY3RpdmUgZGlzdHJpYnV0aW9uIG9mIE4yTyBhbmQgTjJPLWVxIGNvbmNlbnRyYXRpb25zIGFjcm9zcyB0aGUgdGFyZ2V0IHBvcHVsYXRpb24gb2YgbGFrZXMsIGJhc2VkIG9uIDUwMCBkcmF3cyBmcm9tIHRoZSBwb3N0ZXJpb3IgcHJlZGljdGl2ZSBkaXN0cmlidXRpb24uIE5vdGUgdGhhdCB0aGUgeC1heGlzIHdhcyB0cnVuY2F0ZWQgYXQgNTAgbm1vbC9MIGZvciBhIGNsZWFyZXIgdmlzdWFsaXphdGlvbiBvZiB0aGUgYnVsayBvZiB0aGUgcHJlZGljdGVkIGRpc3RyaWJ1dGlvbi4gRm9yIHJlZmVyZW5jZSwgdGhlIG1heCBwcmVkaWN0ZWQgdmFsdWUgd2FzIDQ0MDMuMiBubW9sL0wgZm9yIGRpc3NvbHZlZCBOMk8sIDIwLjQgbm1vbC9MIGZvciBkaXNzb2x2ZWQgTjJPLCBhbmQgNzkzLjUgZm9yIHRoZSBzYXR1cmF0aW9uIHJhdGlvLiANCmBgYHtyIHBsb3RfbjJvX3Bvc3Rlcmlvcl9wcmVkcywgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD00LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvYWxsX3ByZWRpY3Rpb25zLnJkYSIpDQoNCmFsbF9wcmVkaWN0aW9ucyAlPiUNCiAgZ3JvdXBfYnkoLmRyYXcpICU+JSANCiAgc2xpY2Vfc2FtcGxlKG49MWU0KSAlPiUgIyBzaW1wbGUgcmFuZG9tIHNhbXBsZSAxMGsgbGFrZXMNCiAgZ2dwbG90KGFlcyh4ID0gbjJvKSkgKw0KICBzdGF0X2Rpc3Rfc2xhYmludGVydmFsKC53aWR0aCA9IGMoMC41LCAwLjk1KSkgKw0KICBzY2FsZV95X2xvZzEwKCkgKw0KICB4bGltKDAsIDUwKSArDQogIHhsYWIoIkRpc3NvbHZlZCBOMk8gY29uY2VudHJhdGlvbiIpICsNCiAgeWxhYigiZGVuc2l0eSIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCmBgYA0KDQpgYGB7ciBwbG90X24yb2VxX3Bvc3Rlcmlvcl9wcmVkcywgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD00LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvYWxsX3ByZWRpY3Rpb25zLnJkYSIpDQoNCmFsbF9wcmVkaWN0aW9ucyAlPiUNCiAgZ3JvdXBfYnkoLmRyYXcpICU+JSANCiAgc2xpY2Vfc2FtcGxlKG49MWU0KSAlPiUgIyBzaW1wbGUgcmFuZG9tIHNhbXBsZSAxMGsgbGFrZXMNCiAgZ2dwbG90KGFlcyh4ID0gbjJvKSkgKw0KICBzdGF0X2Rpc3Rfc2xhYmludGVydmFsKC53aWR0aCA9IGMoMC41LCAwLjk1KSkgKw0KICBzY2FsZV95X2xvZzEwKCkgKw0KICB4bGltKDAsIDUwKSArDQogIHhsYWIoIkVxdWlsaWJyaXVtIE4yTyBjb25jZW50cmF0aW9uIikgKw0KICB5bGFiKCJkZW5zaXR5IikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KYGBgDQoNCmBgYHtyIHBsb3Rfc2F0X3Bvc3Rlcmlvcl9wcmVkcywgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD00LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvYWxsX3ByZWRpY3Rpb25zLnJkYSIpDQoNCmFsbF9wcmVkaWN0aW9ucyAlPiUNCiAgZ3JvdXBfYnkoLmRyYXcpICU+JSANCiAgc2xpY2Vfc2FtcGxlKG49MWU0KSAlPiUgIyBzaW1wbGUgcmFuZG9tIHNhbXBsZSAxMGsgbGFrZXMNCiAgZ2dwbG90KGFlcyh4ID0gbjJvc2F0KSkgKw0KICBzdGF0X2Rpc3Rfc2xhYmludGVydmFsKC53aWR0aCA9IGMoMC41LCAwLjk1KSkgKw0KICBzY2FsZV95X2xvZzEwKCkgKw0KICB4bGltKDAsIDgpICsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICB4bGFiKCJOMk8gc2F0dXJhdGlvbiByYXRpbyIpICsNCiAgeWxhYigiZGVuc2l0eSIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCmBgYA0KDQojIyBFc3RpbWF0ZWQgbWVhbnMNCiMjIyBOYXRpb25hbA0KQmVsb3cgYXJlIGRlbnNpdHkgcGxvdHMgc3VtbWFyaXppbmcgdGhlIHBvc3RlcmlvciBkaXN0cmlidXRpb24gb2YgX21lYW5zXyBmb3IgTjJPIGNvbmNlbnRyYXRpb25zIGFuZCB0aGUgc2F0dXJhdGlvbiByYXRpbyBmb3IgdGhlIHRhcmdldCBwb3B1bGF0aW9uIChpLmUuLCBhbGwgVVMgbGFrZXMgPiAxaGEgaW4gdGhlIGxvd2VyIDQ4IHN0YXRlcykuDQpgYGB7ciBwbG90X24yb19uYXRfcG9zdGVyaW9yX21lYW4sIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2FsbF9wcmVkaWN0aW9ucy5yZGEiKQ0KDQphbGxfcHJlZGljdGlvbnMgJT4lDQogIGdyb3VwX2J5KC5kcmF3KSAlPiUgDQogIHN1bW1hcmlzZShtZWFuX24ybyA9IG1lYW4objJvKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IG1lYW5fbjJvKSkgKyANCiAgc3RhdF9kaXN0X3NsYWJpbnRlcnZhbCgud2lkdGggPSBjKDAuNSwgMC45NSkpICsNCiAgeGxhYigibWVhbiBkaXNzb2x2ZWQgTjJPIikgKw0KICB5bGFiKCJkZW5zaXR5IikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KYGBgDQoNCmBgYHtyIHBsb3RfbjJvZXFfbmF0X3Bvc3Rlcmlvcl9tZWFuLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTQsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9hbGxfcHJlZGljdGlvbnMucmRhIikNCg0KYWxsX3ByZWRpY3Rpb25zICU+JQ0KICBncm91cF9ieSguZHJhdykgJT4lIA0KICBzdW1tYXJpc2UobWVhbl9uMm8gPSBtZWFuKG4yb2VxKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IG1lYW5fbjJvKSkgKyANCiAgc3RhdF9kaXN0X3NsYWJpbnRlcnZhbCgud2lkdGggPSBjKDAuNSwgMC45NSkpICsNCiAgeGxhYigibWVhbiBlcXVsaWxpYnJpdW0gTjJPIikgKw0KICB5bGFiKCJkZW5zaXR5IikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KYGBgDQoNCmBgYHtyIHBsb3Rfc2F0X25hdF9wb3N0ZXJpb3JfbWVhbiwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD00LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvYWxsX3ByZWRpY3Rpb25zLnJkYSIpDQoNCmFsbF9wcmVkaWN0aW9ucyAlPiUNCiAgZ3JvdXBfYnkoLmRyYXcpICU+JSANCiAgc3VtbWFyaXNlKG1lYW5fc2F0ID0gbWVhbihuMm8vbjJvZXEpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbWVhbl9zYXQpKSArIA0KICBzdGF0X2Rpc3Rfc2xhYmludGVydmFsKC53aWR0aCA9IGMoMC41LCAwLjk1KSkgKw0KICB4bGFiKCJtZWFuIE4yTyBzYXR1cmF0aW9uIHJhdGlvIikgKw0KICB5bGFiKCJkZW5zaXR5IikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KYGBgDQoNClRvIGlsbHVzdHJhdGUgdGhlIHNrZXduZXNzIGluIHRoZSBwcmVkaWN0aXZlIGRpc3RyaWJ1dGlvbiBmb3IgdGhlIHNhdHVyYXRpb24gcmF0aW8sIGFuIGVzdGltYXRlIGZvciB0aGUgbWVkaWFuIHJhdGlvIGlzIHNob3duIGJlbG93LiBUaGUgZW50aXJlIHBvc3RlcmlvciBkaXN0cmlidXRpb24gb2YgdGhlIG1lYW4gYWJvdmUgaXMgbGFyZ2VyIHRoYW4gMSwgdGhlIHJhdGlvIHJlcHJlc2VudGluZyB0aGUgYm91bmRhcnkgb2YgdW5kZXItIF92cy5fIG92ZXJzYXR1cmF0aW9uLiBCeSBjb21wYXJpc29uLCB0aGUgcG9zdGVyaW9yIGVzdGltYXRlIG9mIHRoZSBtZWRpYW4gYmVsb3cgb25seSBpbmNsdWRlZCB2YWx1ZXMgbGVzcyB0aGFuIG9uZSwgc3VnZ2VzdGluZyB0aGF0IHRob3VnaCB0aGUgbWVhbiBzYXR1cmF0aW9uIHJhdGlvIHdhcyBncmVhdGVyIHRoYW4gMSwgbW9zdCBsYWtlcyBpbiB0aGUgbmF0aW9uYWwgcG9wdWxhaXRvbiB3ZXJlIHVuZGVyc2F0dXJhdGVkIChpLmUuLCByYXRpbyBsZXNzIHRoYW4gMSkuIEluIGRpc3RyaWJ1dGlvbnMgd2l0aCByaWdodC1za2V3LCB0aGUgbWVhbiBjYW4gb2Z0ZW4gYmUgY29uc2lkZXJhYmx5IGxhcmdlciB0aGFuIHRoZSBtZWRpYW4uDQpgYGB7ciBwbG90X3NhdF9uYXRfcG9zdGVyaW9yX21lZGlhbiwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD00LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvYWxsX3ByZWRpY3Rpb25zLnJkYSIpDQoNCmFsbF9wcmVkaWN0aW9ucyAlPiUNCiAgZ3JvdXBfYnkoLmRyYXcpICU+JSANCiAgc3VtbWFyaXNlKG1lZGlhbl9zYXQgPSBtZWRpYW4objJvL24yb2VxKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IG1lZGlhbl9zYXQpKSArIA0KICBzdGF0X2Rpc3Rfc2xhYmludGVydmFsKC53aWR0aCA9IGMoMC41LCAwLjk1KSkgKw0KICB4bGFiKCJtZWRpYW4gTjJPIHNhdHVyYXRpb24gcmF0aW8iKSArDQogIHlsYWIoImRlbnNpdHkiKSArDQogIHRoZW1lX3RpZHliYXllcygpDQpgYGANCg0KQmVsb3cgaXMgYSBwbG90IG9mIHRoZSBwb3N0ZXJpb3IgbWVhbiBlc3RpbWF0ZSBmb3IgdGhlIHByb3BvcnRpb24gb2YgdW5zYXR1cmF0ZWQgbGFrZXMgYXQgdGhlIG5hdGlvbmFsIHNjYWxlLg0KYGBge3IgcGxvdF91bmRlcnNhdF9wb3N0ZXJpb3JfbWVhbiwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD00LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvYWxsX3ByZWRpY3Rpb25zLnJkYSIpDQoNCmFsbF9wcmVkaWN0aW9ucyAlPiUNCiAgZ3JvdXBfYnkoLmRyYXcpICU+JQ0KICBzdW1tYXJpc2UocHJvcF9zYXQgPSBzdW0objJvc2F0IDwgMSkgLyBsZW5ndGgodW5pcXVlKC5yb3cpKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHByb3Bfc2F0KSkgKyANCiAgc3RhdF9zbGFiaW50ZXJ2YWwoLndpZHRoID0gYygwLjUsIDAuOTUpKSArDQogIHhsYWIoIlByb3BvcnRpb24gb2YgdW5kZXJzYXR1cmF0ZWQgd2F0ZXJib2RpZXMiKSArDQogIHlsYWIoImRlbnNpdHkiKSArDQogIHRoZW1lX3RpZHliYXllcygpDQpgYGANCg0KIyMjIEVjb3JlZ2lvbg0KQmVsb3cgYXJlIHBvc3RlcmlvciBlc3RpbWF0ZXMgb2YgdGhlIG1lYW5zIGZvciBkaXNzb2x2ZWQgYW5kIGVxdWlsaWJyaXVtIE4yTyBhbmQgdGhlIHNhdHVyYXRpb24gcmF0aW8gYnkgV1NBOSBlY29yZWdpb24uDQpgYGB7ciBwbG90X24yb193c2E5X3Bvc3Rlcmlvcl9tZWFuLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTQsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9hbGxfcHJlZGljdGlvbnMucmRhIikNCg0KYWxsX3ByZWRpY3Rpb25zICU+JQ0KICBncm91cF9ieShXU0E5LCAuZHJhdykgJT4lDQogIHN1bW1hcmlzZShtZWFuX24ybyA9IG1lYW4objJvKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIG11dGF0ZShlY29yZWdpb24gPSBXU0E5KSAlPiUNCiAgZ2dwbG90KCkgKyANCiAgc3RhdF9zbGFiaW50ZXJ2YWwoYWVzKHggPSBtZWFuX24ybywgDQogICAgICAgICAgICAgICAgICAgICAgICB5ID0gcmVvcmRlcihlY29yZWdpb24sIG1lYW5fbjJvKSksIA0KICAgICAgICAgICAgICAgICAgICBxdWFudGlsZXMgPSAxMDAsDQogICAgICAgICAgICAgICAgICAgIC53aWR0aCA9IGMoMC41LCAwLjk1KSkgKw0KICB4bGFiKCJtZWFuIGRpc3NvbHZlZCBOMk8iKSArDQogIHlsYWIoImRlbnNpdHkiKSArDQogIHRoZW1lX3RpZHliYXllcygpDQpgYGANCg0KYGBge3IgcGxvdF9uMm9lcV93c2E5X3Bvc3Rlcmlvcl9tZWFuLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTQsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9hbGxfcHJlZGljdGlvbnMucmRhIikNCg0KYWxsX3ByZWRpY3Rpb25zICU+JQ0KICBncm91cF9ieShXU0E5LCAuZHJhdykgJT4lDQogIHN1bW1hcmlzZShtZWFuX24yb2VxID0gbWVhbihuMm9lcSksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICBtdXRhdGUoZWNvcmVnaW9uID0gV1NBOSkgJT4lDQogIGdncGxvdCgpICsgDQogIHN0YXRfc2xhYmludGVydmFsKGFlcyh4ID0gbWVhbl9uMm9lcSwgDQogICAgICAgICAgICAgICAgICAgICAgICB5ID0gcmVvcmRlcihlY29yZWdpb24sIG1lYW5fbjJvZXEpKSwgDQogICAgICAgICAgICAgICAgICAgIC53aWR0aCA9IGMoMC41LCAwLjk1KSkgKw0KICB4bGFiKCJtZWFuIGVxdWlsaWJyaXVtIE4yTyIpICsNCiAgeWxhYigiZGVuc2l0eSIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCmBgYA0KDQpgYGB7ciBwbG90X3NhdF93c2E5X3Bvc3Rlcmlvcl9tZWFuLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTQsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9hbGxfcHJlZGljdGlvbnMucmRhIikNCg0KYWxsX3ByZWRpY3Rpb25zICU+JQ0KICBncm91cF9ieShXU0E5LCAuZHJhdykgJT4lDQogIHN1bW1hcmlzZShtZWFuX3NhdCA9IG1lYW4objJvL24yb2VxKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIG11dGF0ZShlY29yZWdpb24gPSBXU0E5KSAlPiUNCiAgZ2dwbG90KCkgKyANCiAgc3RhdF9zbGFiaW50ZXJ2YWwoYWVzKHggPSBtZWFuX3NhdCwNCiAgICAgICAgICAgICAgICAgICAgICAgIHkgPSByZW9yZGVyKGVjb3JlZ2lvbiwgbWVhbl9zYXQpKSwNCiAgICAgICAgICAgICAgICAgICAgLndpZHRoID0gYygwLjUsIDAuOTUpKSArDQogIHhsYWIoIm1lYW4gTjJPIHNhdHVyYXRpb24gcmF0aW8iKSArDQogIHlsYWIoImRlbnNpdHkiKSArDQogIHRoZW1lX3RpZHliYXllcygpDQpgYGANCg0KQSBwbG90IG9mIHRoZSBwb3N0ZXJpb3IgZXN0aW1hdGVzIGZvciB0aGUgbWVkaWFuIHNhdHVyYXRpb24gcmF0aW8gYmVsb3cgaW5kaWNhdGVkLCBhZ2FpbiwgdGhhdCBtb3N0IGxha2VzIGluIGVhY2ggZWNvcmVnaW9uIHdlcmUgdW5kZXJzYXR1cmF0ZWQgKGkuZS4sIG1lZGlhbiA8PCAxKS4NCmBgYHtyIHBsb3Rfc2F0X3dzYTlfcG9zdGVyaW9yX21lZGlhbiwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD00LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvYWxsX3ByZWRpY3Rpb25zLnJkYSIpDQoNCmFsbF9wcmVkaWN0aW9ucyAlPiUNCiAgZ3JvdXBfYnkoV1NBOSwgLmRyYXcpICU+JQ0KICBzdW1tYXJpc2UobWVkaWFuX3NhdCA9IG1lZGlhbihuMm8vbjJvZXEpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgbXV0YXRlKGVjb3JlZ2lvbiA9IFdTQTkpICU+JQ0KICBnZ3Bsb3QoKSArIA0KICBzdGF0X3NsYWJpbnRlcnZhbChhZXMoeCA9IG1lZGlhbl9zYXQsDQogICAgICAgICAgICAgICAgICAgICAgICB5ID0gcmVvcmRlcihlY29yZWdpb24sIG1lZGlhbl9zYXQpKSwNCiAgICAgICAgICAgICAgICAgICAgLndpZHRoID0gYygwLjUsIDAuOTUpKSArDQogIHhsYWIoIm1lZGlhbiBOMk8gc2F0dXJhdGlvbiByYXRpbyIpICsNCiAgeWxhYigiZGVuc2l0eSIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCmBgYA0KDQpBIHBsb3Qgb2YgdGhlIGVzdGltYXRlcyBvZiB0aGUgcHJvcG9ydGlvbiBvZiB1bmRlci1zYXR1cmF0ZWQgbGFrZXMgYnkgZWNvcmVnaW9uIGlzIGJlbG93Lg0KQSBwbG90IG9mIHRoZSBwb3N0ZXJpb3IgZXN0aW1hdGVzIGZvciB0aGUgbWVkaWFuIHNhdHVyYXRpb24gcmF0aW8gYmVsb3cgaW5kaWNhdGVkLCBhZ2FpbiwgdGhhdCBtb3N0IGxha2VzIGluIGVhY2ggZWNvcmVnaW9uIHdlcmUgdW5kZXJzYXR1cmF0ZWQgKGkuZS4sIG1lZGlhbiA8PCAxKS4NCmBgYHtyIHBsb3RfcHJvcF9zYXRfd3NhOV9wb3N0ZXJpb3JfbWVkaWFuLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTQsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9hbGxfcHJlZGljdGlvbnMucmRhIikNCg0KYWxsX3ByZWRpY3Rpb25zICU+JQ0KICBncm91cF9ieShXU0E5LCAuZHJhdykgJT4lDQogIHN1bW1hcmlzZShwcm9wX3NhdCA9IHN1bShuMm9zYXQgPCAxKSAvIGxlbmd0aCh1bmlxdWUoLnJvdykpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgbXV0YXRlKGVjb3JlZ2lvbiA9IFdTQTkpICU+JQ0KICBnZ3Bsb3QoKSArIA0KICBzdGF0X3NsYWJpbnRlcnZhbChhZXMoeCA9IHByb3Bfc2F0LA0KICAgICAgICAgICAgICAgICAgICAgICAgeSA9IHJlb3JkZXIoZWNvcmVnaW9uLCBwcm9wX3NhdCkpLA0KICAgICAgICAgICAgICAgICAgICAud2lkdGggPSBjKDAuNSwgMC45NSkpICsNCiAgeGxhYigiUHJvcG9ydGlvbiBvZiB1bmRlcnNhdHVyYXRlZCBsYWtlcyIpICsNCiAgeWxhYigiZGVuc2l0eSIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCmBgYA0KDQojIyMgU3RhdGUNCkNvbXBhcmlzb25zIG9mIG1lYW4gZXN0aW1hdGVzIChwb3N0ZXJpb3IgbWVkaWFuLCB1cHBlciBhbmQgbG93ZXIgOTV0aCBwZXJjZW50aWxlcykgYnkgc3RhdGUgYXJlIGJlbG93LiBEZW5zaXR5IGVzdGltYXRlcyB3ZXJlIG5vdCBpbmNsdWRlZCB0byBtaW5pbWl6ZSBwbG90IHNwYWNlLg0KYGBge3IgcGxvdF9zdGF0ZV9tZWFuX24ybywgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTUsIGZpZy53aWR0aD04LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvYWxsX3ByZWRpY3Rpb25zLnJkYSIpDQoNCmFsbF9wcmVkaWN0aW9ucyAlPiUNCiAgZ3JvdXBfYnkoc3RhdGUsIC5kcmF3KSAlPiUNCiAgc3VtbWFyaXNlKG1lYW5fbjJvID0gbWVhbihuMm8pLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgZ3JvdXBfYnkoc3RhdGUpICU+JQ0KICBzdW1tYXJpc2UoZXN0aW1hdGUgPSByb3VuZChtZWRpYW4obWVhbl9uMm8pLCAxKSwNCiAgICBMQ0wgPSByb3VuZChxdWFudGlsZShtZWFuX24ybywgcHJvYnMgPSAwLjAyNSksIDEpLA0KICAgIFVDTCA9IHJvdW5kKHF1YW50aWxlKG1lYW5fbjJvLCBwcm9icyA9IDAuOTc1KSwgMSksDQogICAgLmdyb3VwcyA9ICJkcm9wIikgJT4lIA0KICBzZWxlY3Qoc3RhdGUsIGVzdGltYXRlLCBMQ0wsIFVDTCkgJT4lDQogIG11dGF0ZShzdGF0ZSA9IGZvcmNhdHM6OmZjdF9yZW9yZGVyKHN0YXRlLCBlc3RpbWF0ZSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBzdGF0ZSwgeSA9IGVzdGltYXRlICkpICsNCiAgZ2VvbV9wb2ludChwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpKSArDQogIGdlb21fbGluZXJhbmdlKGFlcyh5bWluID0gTENMLCB5bWF4ID0gVUNMKSwNCiAgICAgICAgICAgICAgICAgcG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSkgKw0KICB5bGFiKCJtZWFuIGRpc3NvbHZlZCBOMk8iKSArDQogIHNjYWxlX3lfY29udGludW91cyhwb3NpdGlvbiA9ICJsZWZ0IikgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplPTksIGFuZ2xlPTQ1KSkNCmBgYA0KDQpgYGB7ciBwbG90X3N0YXRlX21lYW5fbjJvZXEsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD01LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2FsbF9wcmVkaWN0aW9ucy5yZGEiKQ0KDQphbGxfcHJlZGljdGlvbnMgJT4lDQogIGdyb3VwX2J5KHN0YXRlLCAuZHJhdykgJT4lDQogIHN1bW1hcmlzZShtZWFuX24yb2VxID0gbWVhbihuMm9lcSksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICBncm91cF9ieShzdGF0ZSkgJT4lDQogIHN1bW1hcmlzZShlc3RpbWF0ZSA9IHJvdW5kKG1lZGlhbihtZWFuX24yb2VxKSwgMSksDQogICAgTENMID0gcm91bmQocXVhbnRpbGUobWVhbl9uMm9lcSwgcHJvYnMgPSAwLjAyNSksIDEpLA0KICAgIFVDTCA9IHJvdW5kKHF1YW50aWxlKG1lYW5fbjJvZXEsIHByb2JzID0gMC45NzUpLCAxKSwNCiAgICAuZ3JvdXBzID0gImRyb3AiKSAlPiUgDQogIHNlbGVjdChzdGF0ZSwgZXN0aW1hdGUsIExDTCwgVUNMKSAlPiUNCiAgbXV0YXRlKHN0YXRlID0gZm9yY2F0czo6ZmN0X3Jlb3JkZXIoc3RhdGUsIGVzdGltYXRlKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHN0YXRlLCB5ID0gZXN0aW1hdGUgKSkgKw0KICBnZW9tX3BvaW50KHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpICsNCiAgZ2VvbV9saW5lcmFuZ2UoYWVzKHltaW4gPSBMQ0wsIHltYXggPSBVQ0wpLA0KICAgICAgICAgICAgICAgICBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpKSArDQogIHlsYWIoIm1lYW4gZXF1aWxpYnJpdW0gTjJPIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMocG9zaXRpb24gPSAibGVmdCIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplPTksIGFuZ2xlPTQ1KSkNCmBgYA0KDQpCZWxvdywgYSBwbG90IG9mIGVzdGltYXRlcyBmb3IgdGhlIG1lYW4gKGJsYWNrIGNpcmNsZXMpIGFuZCBtZWRpYW4gKGdyZXkgY2lyY2xlcykgc2F0dXJhdGlvbiByYXRpbyBieSBzdGF0ZS4gQSBob3Jpem9udGFsLCBkYXNoZWQsIGJsYWNrIGxpbmUgaXMgc2hvd24gYXQgcmF0aW8gPSAxLCBpbmRpY2F0aW5nIHRoZSBib3VuZGFyeSBmb3IgdW5kZXItIF92cy5fIG92ZXJzYXR1cmF0aW9uLiBPbmx5IGEgZmV3IHN0YXRlcyAoZS5nLiwgTlYsIERFKSBoYWQgbWVkaWFuIGVzdGltYXRlcyB0aGF0IHdlcmUgMSBvciBncmVhdGVyLCBzdWdnZXN0aW5nIHRoYXQsIGZvciBtb3N0IHN0YXRlcywgbW9zdCBsYWtlcyB3ZXJlIHVuZGVyc2F0dXJhdGVkLg0KYGBge3IgcGxvdF9zdGF0ZV9tZWFuX21lZGlhbl9zYXQsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD01LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2FsbF9wcmVkaWN0aW9ucy5yZGEiKQ0KDQphbGxfcHJlZGljdGlvbnMgJT4lDQogIGdyb3VwX2J5KHN0YXRlLCAuZHJhdykgJT4lDQogIHN1bW1hcmlzZShtZWFuX3NhdCA9IG1lYW4objJvc2F0KSwgDQogICAgICAgICAgICBtZWRpYW5fc2F0ID0gbWVkaWFuKG4yb3NhdCksDQogICAgICAgICAgICAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgZ3JvdXBfYnkoc3RhdGUpICU+JQ0KICBzdW1tYXJpc2UoZXN0aW1hdGVfbWVhbiA9IHJvdW5kKG1lZGlhbihtZWFuX3NhdCksIDQpLA0KICAgIExDTF9tZWFuID0gcm91bmQocXVhbnRpbGUobWVhbl9zYXQsIHByb2JzID0gMC4wMjUpLCA0KSwNCiAgICBVQ0xfbWVhbiA9IHJvdW5kKHF1YW50aWxlKG1lYW5fc2F0LCBwcm9icyA9IDAuOTc1KSwgNCksDQogICAgZXN0aW1hdGVfbWVkaWFuID0gcm91bmQobWVkaWFuKG1lZGlhbl9zYXQpLCA0KSwNCiAgICBMQ0xfbWVkaWFuID0gcm91bmQocXVhbnRpbGUobWVkaWFuX3NhdCwgcHJvYnMgPSAwLjAyNSksIDQpLA0KICAgIFVDTF9tZWRpYW4gPSByb3VuZChxdWFudGlsZShtZWRpYW5fc2F0LCBwcm9icyA9IDAuOTc1KSwgNCksDQogICAgLmdyb3VwcyA9ICJkcm9wIikgJT4lIA0KICBzZWxlY3Qoc3RhdGUsIA0KICAgICAgICAgZXN0aW1hdGVfbWVhbiwgDQogICAgICAgICBlc3RpbWF0ZV9tZWRpYW4sIA0KICAgICAgICAgTENMX21lYW4sDQogICAgICAgICBMQ0xfbWVkaWFuLA0KICAgICAgICAgVUNMX21lYW4sDQogICAgICAgICBVQ0xfbWVkaWFuKSAlPiUNCiAgbXV0YXRlKHN0YXRlID0gZm9yY2F0czo6ZmN0X3Jlb3JkZXIoc3RhdGUsIGVzdGltYXRlX21lYW4pKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gc3RhdGUsIHkgPSBlc3RpbWF0ZV9tZWFuICkpICsNCiAgZ2VvbV9wb2ludChwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpLA0KICAgICAgICAgICAgIHNpemUgPSAyKSArDQogIGdlb21fbGluZXJhbmdlKGFlcyh5bWluID0gTENMX21lYW4sIHltYXggPSBVQ0xfbWVhbiksDQogICAgICAgICAgICAgICAgIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpICsNCiAgZ2VvbV9wb2ludChhZXMoeCA9IHN0YXRlLCB5ID0gZXN0aW1hdGVfbWVkaWFuKSwgDQogICAgICAgICAgICAgcG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSwNCiAgICAgICAgICAgICBjb2xvciA9ICJncmV5IiwNCiAgICAgICAgICAgICBzaXplID0gMikgKw0KICBnZW9tX2xpbmVyYW5nZShhZXMoeW1pbiA9IExDTF9tZWRpYW4sIHltYXggPSBVQ0xfbWVkaWFuKSwNCiAgICAgICAgICAgICAgICAgcG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSwNCiAgICAgICAgICAgICAgICAgY29sb3IgPSAiZ3JheSIpICsNCiAgeWxhYigibWVhbiBhbmQgbWVkaWFuIE4yTyBzYXR1cmF0aW9uIHJhdGlvIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMocG9zaXRpb24gPSAibGVmdCIpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMSwgY29sb3IgPSAiYmxhY2siLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZT05LCBhbmdsZT00NSkpDQpgYGANCg0KRmluYWxseSwgYSBwbG90IG9mIHRoZSBlc3RpbWF0ZWQgcHJvcG9ydGlvbiBvZiB1bmRlcnNhdHVyYXRlZCBsYWtlcyBmb3IgZWFjaCBzdGF0ZSBpbiB0aGUgdGFyZ2V0IHBvcHVsYXRpb24uIFBvaW50IGVzdGltYXRlcyBhcmUgdGhlIHBvc3RlcmlvciBtZWRpYW4gb2YgdGhlIHByb3BvcnRpb24gYW5kIGJhcnMgYXJlIHRoZSB1cHBlciBhbmQgbG93ZXIgYm91bmRhcmllcyBvZiB0aGUgY2VudHJhbCA5NXRoIHBlcmNlbnRpbGUgb2YgdGhlIHBvc3RlcmlvciBkaXN0cmlidXRpb25zIG9mIHByb3BvcnRpb25zLg0KYGBge3IgcGxvdF9zdGF0ZV9wcm9wX3NhdCwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTUsIGZpZy53aWR0aD04LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvYWxsX3ByZWRpY3Rpb25zLnJkYSIpDQoNCmFsbF9wcmVkaWN0aW9ucyAlPiUNCiAgZ3JvdXBfYnkoc3RhdGUsIC5kcmF3KSAlPiUNCiAgc3VtbWFyaXNlKHByb3Bfc2F0ID0gc3VtKG4yb3NhdCA8IDEpIC8gbGVuZ3RoKHVuaXF1ZSgucm93KSksDQogICAgICAgICAgICAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgZ3JvdXBfYnkoc3RhdGUpICU+JQ0KICBzdW1tYXJpc2UoZXN0aW1hdGUgPSByb3VuZChtZWRpYW4ocHJvcF9zYXQpLCA0KSwNCiAgICBMQ0wgPSByb3VuZChxdWFudGlsZShwcm9wX3NhdCwgcHJvYnMgPSAwLjAyNSksIDQpLA0KICAgIFVDTCA9IHJvdW5kKHF1YW50aWxlKHByb3Bfc2F0LCBwcm9icyA9IDAuOTc1KSwgNCksDQogICAgLmdyb3VwcyA9ICJkcm9wIikgJT4lIA0KICBzZWxlY3Qoc3RhdGUsIA0KICAgICAgICAgZXN0aW1hdGUsIA0KICAgICAgICAgTENMLA0KICAgICAgICAgVUNMKSAlPiUNCiAgbXV0YXRlKHN0YXRlID0gZm9yY2F0czo6ZmN0X3Jlb3JkZXIoc3RhdGUsIGVzdGltYXRlKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHN0YXRlLCB5ID0gZXN0aW1hdGUpKSArDQogIGdlb21fcG9pbnQocG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSwNCiAgICAgICAgICAgICBzaXplID0gMikgKw0KICBnZW9tX2xpbmVyYW5nZShhZXMoeW1pbiA9IExDTCwgeW1heCA9IFVDTCksDQogICAgICAgICAgICAgICAgIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpICsNCiAgeWxhYigiUHJvcG9ydGlvbiBvZiB1bmRlcnNhdHVyYXRlZCBsYWtlcyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHBvc2l0aW9uID0gImxlZnQiKSArDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZT05LCBhbmdsZT00NSkpDQpgYGANCg0KIyMjIFNpemUgY2F0ZWdvcnkNClRoZSBlc3RpbWF0ZWQgbWVhbnMgYnkgc2l6ZSBjYXRlZ29yeSBhcmUgYmVsb3cgZm9yIGRpc3NvbHZlZCBhbmQgZXF1aWxpYnJpdW0gTjJPIGFuZCB0aGUgc2F0dXJhdGlvbiByYXRpby4gTWVkaWFuIGVzdGltYXRlcyBmb3IgdGhlIHNhdHVyYXRpb24gcmF0aW8gYXJlIGFsc28gc2hvd24uDQpgYGB7ciBwbG90X24yb19zaXplX3Bvc3Rlcmlvcl9tZWFuLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTQsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9hbGxfcHJlZGljdGlvbnMucmRhIikNCg0KYWxsX3ByZWRpY3Rpb25zICU+JQ0KICBncm91cF9ieShzaXplX2NhdCwgLmRyYXcpICU+JQ0KICBzdW1tYXJpc2UobWVhbl9uMm8gPSBtZWFuKG4ybyksDQogICAgICAgICAgICAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbWVhbl9uMm8sIHkgPSBzaXplX2NhdCkpICsgDQogIHN0YXRfc2xhYmludGVydmFsKC53aWR0aCA9IGMoMC41LCAwLjk1KSkgKw0KICB4bGFiKCJtZWFuIGRpc3NvbHZlZCBOMk8iKSArDQogIHlsYWIoImRlbnNpdHkiKSArDQogIHRoZW1lX3RpZHliYXllcygpDQpgYGANCg0KYGBge3IgcGxvdF9uMm9lcV9zaXplX3Bvc3Rlcmlvcl9tZWFuLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTQsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9hbGxfcHJlZGljdGlvbnMucmRhIikNCg0KYWxsX3ByZWRpY3Rpb25zICU+JQ0KICBncm91cF9ieShzaXplX2NhdCwgLmRyYXcpICU+JQ0KICBzdW1tYXJpc2UobWVhbl9uMm8gPSBtZWFuKG4yb2VxKSwNCiAgICAgICAgICAgIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBtZWFuX24ybywgeSA9IHNpemVfY2F0KSkgKyANCiAgc3RhdF9zbGFiaW50ZXJ2YWwoLndpZHRoID0gYygwLjUsIDAuOTUpKSArDQogIHhsYWIoIm1lYW4gZXF1aWxpYnJpdW0gTjJPIikgKw0KICB5bGFiKCJkZW5zaXR5IikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KYGBgDQoNCmBgYHtyIHBsb3Rfc2F0X3NpemVfcG9zdGVyaW9yX21lYW4sIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9NCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2FsbF9wcmVkaWN0aW9ucy5yZGEiKQ0KDQphbGxfcHJlZGljdGlvbnMgJT4lDQogIGdyb3VwX2J5KHNpemVfY2F0LCAuZHJhdykgJT4lDQogIHN1bW1hcmlzZShtZWFuX24ybyA9IG1lYW4objJvc2F0KSwNCiAgICAgICAgICAgIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBtZWFuX24ybywgeSA9IHNpemVfY2F0KSkgKyANCiAgc3RhdF9zbGFiaW50ZXJ2YWwoLndpZHRoID0gYygwLjUsIDAuOTUpKSArDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDEsIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbG9yID0gImJsYWNrIikgKw0KICB4bGFiKCJtZWFuIE4yTyBzYXR1cmF0aW9uIHJhdGlvIikgKw0KICB5bGFiKCJkZW5zaXR5IikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KYGBgDQoNCmBgYHtyIHBsb3Rfc2F0X3NpemVfcG9zdGVyaW9yX21lZGlhbiwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD00LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvYWxsX3ByZWRpY3Rpb25zLnJkYSIpDQoNCmFsbF9wcmVkaWN0aW9ucyAlPiUNCiAgZ3JvdXBfYnkoc2l6ZV9jYXQsIC5kcmF3KSAlPiUNCiAgc3VtbWFyaXNlKG1lYW5fbjJvID0gbWVkaWFuKG4yb3NhdCksDQogICAgICAgICAgICAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbWVhbl9uMm8sIHkgPSBzaXplX2NhdCkpICsgDQogIHN0YXRfc2xhYmludGVydmFsKC53aWR0aCA9IGMoMC41LCAwLjk1KSkgKw0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAxLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvciA9ICJibGFjayIpICsNCiAgeGxhYigibWVkaWFuIE4yTyBzYXR1cmF0aW9uIHJhdGlvIikgKw0KICB5bGFiKCJkZW5zaXR5IikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KYGBgDQoNCk1lYW4gX3ZzLl8gbWVkaWFuIGJlbG93Lg0KYGBge3IgcGxvdF9zaXplX2NhdF9tZWFuX21lZGlhbl9zYXQsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD01LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2FsbF9wcmVkaWN0aW9ucy5yZGEiKQ0KDQphbGxfcHJlZGljdGlvbnMgJT4lDQogIGdyb3VwX2J5KHNpemVfY2F0LCAuZHJhdykgJT4lDQogIHN1bW1hcmlzZShtZWFuX3NhdCA9IG1lYW4objJvc2F0KSwgDQogICAgICAgICAgICBtZWRpYW5fc2F0ID0gbWVkaWFuKG4yb3NhdCksDQogICAgICAgICAgICAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgZ3JvdXBfYnkoc2l6ZV9jYXQpICU+JQ0KICBzdW1tYXJpc2UoZXN0aW1hdGVfbWVhbiA9IHJvdW5kKG1lZGlhbihtZWFuX3NhdCksIDIpLA0KICAgIExDTF9tZWFuID0gcm91bmQocXVhbnRpbGUobWVhbl9zYXQsIHByb2JzID0gMC4wMjUpLCAyKSwNCiAgICBVQ0xfbWVhbiA9IHJvdW5kKHF1YW50aWxlKG1lYW5fc2F0LCBwcm9icyA9IDAuOTc1KSwgMiksDQogICAgZXN0aW1hdGVfbWVkaWFuID0gcm91bmQobWVkaWFuKG1lZGlhbl9zYXQpLCAyKSwNCiAgICBMQ0xfbWVkaWFuID0gcm91bmQocXVhbnRpbGUobWVkaWFuX3NhdCwgcHJvYnMgPSAwLjAyNSksIDIpLA0KICAgIFVDTF9tZWRpYW4gPSByb3VuZChxdWFudGlsZShtZWRpYW5fc2F0LCBwcm9icyA9IDAuOTc1KSwgMiksDQogICAgLmdyb3VwcyA9ICJkcm9wIikgJT4lIA0KICBzZWxlY3Qoc2l6ZV9jYXQsIA0KICAgICAgICAgZXN0aW1hdGVfbWVhbiwgDQogICAgICAgICBlc3RpbWF0ZV9tZWRpYW4sIA0KICAgICAgICAgTENMX21lYW4sDQogICAgICAgICBMQ0xfbWVkaWFuLA0KICAgICAgICAgVUNMX21lYW4sDQogICAgICAgICBVQ0xfbWVkaWFuKSAlPiUNCiAgbXV0YXRlKHN0YXRlID0gZm9yY2F0czo6ZmN0X3Jlb3JkZXIoc2l6ZV9jYXQsIGVzdGltYXRlX21lYW4pKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gc2l6ZV9jYXQsIHkgPSBlc3RpbWF0ZV9tZWFuICkpICsNCiAgZ2VvbV9wb2ludChwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpLA0KICAgICAgICAgICAgIHNpemUgPSAyKSArDQogIGdlb21fbGluZXJhbmdlKGFlcyh5bWluID0gTENMX21lYW4sIHltYXggPSBVQ0xfbWVhbiksDQogICAgICAgICAgICAgICAgIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpICsNCiAgZ2VvbV9wb2ludChhZXMoeCA9IHNpemVfY2F0LCB5ID0gZXN0aW1hdGVfbWVkaWFuKSwgDQogICAgICAgICAgICAgcG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSwNCiAgICAgICAgICAgICBjb2xvciA9ICJncmV5IiwNCiAgICAgICAgICAgICBzaXplID0gMikgKw0KICBnZW9tX2xpbmVyYW5nZShhZXMoeW1pbiA9IExDTF9tZWRpYW4sIHltYXggPSBVQ0xfbWVkaWFuKSwNCiAgICAgICAgICAgICAgICAgcG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSwNCiAgICAgICAgICAgICAgICAgY29sb3IgPSAiZ3JheSIpICsNCiAgeWxhYigibWVhbiBhbmQgbWVkaWFuIE4yTyBzYXR1cmF0aW9uIHJhdGlvIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMocG9zaXRpb24gPSAibGVmdCIpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMSwgY29sb3IgPSAiYmxhY2siLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZT05LCBhbmdsZT00NSkpDQpgYGANCg0KQW5kLCBmaW5hbGx5LCB0aGUgZXN0aW1hdGVkIHByb3BvcnRpb24gb2YgdW5kZXJzYXR1cmF0ZWQgbGFrZXMgaW4gdGhlIHRhcmdldCBwb3B1bGF0aW9uIGJ5IHNpemUgY2F0ZWdvcnkNCmBgYHtyIHBsb3RfcHJvcF9zYXRfc2l6ZV9jYXRfcG9zdGVyaW9yX21lZGlhbiwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD00LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvYWxsX3ByZWRpY3Rpb25zLnJkYSIpDQoNCmFsbF9wcmVkaWN0aW9ucyAlPiUNCiAgZ3JvdXBfYnkoc2l6ZV9jYXQsIC5kcmF3KSAlPiUNCiAgc3VtbWFyaXNlKHByb3Bfc2F0ID0gc3VtKG4yb3NhdCA8IDEpIC8gbGVuZ3RoKHVuaXF1ZSgucm93KSksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICBnZ3Bsb3QoKSArIA0KICBzdGF0X3NsYWJpbnRlcnZhbChhZXMoeCA9IHByb3Bfc2F0LA0KICAgICAgICAgICAgICAgICAgICAgICAgeSA9IHJlb3JkZXIoc2l6ZV9jYXQsIHByb3Bfc2F0KSksDQogICAgICAgICAgICAgICAgICAgIC53aWR0aCA9IGMoMC41LCAwLjk1KSkgKw0KICB4bGFiKCJQcm9wb3J0aW9uIG9mIHVuZGVyc2F0dXJhdGVkIGxha2VzIikgKw0KICB5bGFiKCJkZW5zaXR5IikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KYGBgDQoNCiMjIE1vZGVsLSBfdnMuXyBkZXNpZ24tYmFzZWQNCkJlbG93LCBlc3RpbWF0ZXMgZnJvbSB0aGUgbW9kZWwtYmFzZWQgYXBwcm9hY2ggYXJlIGNvbXBhcmVkIHRvIGRlc2lnbi1iYXNlZCBlc3RpbWF0ZXMuIEluIGdlbmVyYWwsIHRoZSBtb2RlbCBlc3RpbWF0ZXMgd2VyZSBzaW1pbGFyIHRvIHRoZSBkZXNpZ24tYmFzZWQgZXN0aW1hdGVzLiBNb2RlbCBlc3RpbWF0ZXMgd2VyZSB0eXBpY2FsbHkgd2l0aGluIHRoZSBjb25maWRlbmNlIGJvdW5kcyBvZiB0aGUgZGVzaWduLWJhc2VkIGVzdGltYXRlcywgYnV0IHdpdGggbXVjaCBncmVhdGVyIHByZWNpc2lvbi4gSW1wcm92ZWQgcHJlY2lzaW9uIHdhcyBleHBlY3RlZCBkdWUgdG8gdGhlICJzaHJpbmthZ2UiIGluZHVjZWQgYnkgdGhlIG11bHRpbGV2ZWwgcGFyYW1ldGVyaXphdGlvbiwgd2hpY2ggYWxsb3dlZCBzb21lICJib3Jyb3dpbmciIG9mIGluZm9ybWF0aW9uIGFjcm9zcyB0aGUgdmFyaW91cyBsZXZlbHMgb2YgdGhlIHN1cnZleSBmYWN0b3JzLiANCg0KIyMjIERpc3NvbHZlZCBOMk8NCkJlbG93LCBOYXRpb25hbCBtZWFuIGVzdGltYXRlcyBmb3IgZGlzc29sdmVkIE4yTyBmcm9tIHRoZSBtb2RlbCBhbmQgZGVzaWduLWJhc2VkIGFwcHJvYWNoZXMgd2VyZSBjb21wYXJlZC4gVGhlIHNhbXBsZS1iYXNlZCBlc3RpbWF0ZSB3YXMgYWxzbyBpbmNsdWRlZCBhcyBhIG5haXZlIHJlZmVyZW5jZS4NCmBgYHtyIG4yb19tZWFuc19uYXRpb25hbCwgbWVzc2FnZT1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2RmX21vZGVsLnJkYSIpDQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fc3VydmV5X2VzdHMucmRhIikNCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2FsbF9wcmVkaWN0aW9ucy5yZGEiKQ0KDQphbGxfcHJlZGljdGlvbnMgJT4lDQogIGdyb3VwX2J5KC5kcmF3KSAlPiUNCiAgc3VtbWFyaXNlKG1lYW5fbjJvID0gbWVhbihuMm8pKSAlPiUNCiAgc3VtbWFyaXNlKGVzdGltYXRlID0gcm91bmQobWVkaWFuKG1lYW5fbjJvKSwgMiksICMgcG9zdGVyaW9yIG1lZGlhbg0KICAgIExDTCA9IHJvdW5kKHF1YW50aWxlKG1lYW5fbjJvLCBwcm9icyA9IDAuMDI1KSwgMiksDQogICAgVUNMID0gcm91bmQocXVhbnRpbGUobWVhbl9uMm8sIHByb2JzID0gMC45NzUpLCAyKSkgJT4lIA0KICBtdXRhdGUodHlwZSA9ICJtb2RlbCIpICU+JQ0KICBiaW5kX3Jvd3MoY2JpbmQobjJvX3N1cnZleV9lc3RzWzEwLCAyOjRdLCB0eXBlID0gcmVwKCJzdXJ2ZXkiLCAxKSkpICU+JQ0KICBhZGRfcm93KGVzdGltYXRlID0gcm91bmQobWVhbihkZl9tb2RlbCRuMm8pLCAyKSwNCiAgICAgICAgICB0eXBlID0gInNhbXBsZSIpICU+JQ0KICBwcmludCgpDQpgYGANCg0KVGhlIGJsYWNrLCB2ZXJ0aWNhbCwgZGFzaGVkIGxpbmUgaW4gdGhlIGZpZ3VyZSBiZWxvdyByZXByZXNlbnRzIHRoZSBtZWFuIG9mIHRoZSBzYW1wbGUuIA0KYGBge3IgcGxvdF9uMm9fbWVhbnNfbmF0aW9uYWwsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD0yLCBmaWcud2lkdGg9NCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2RmX21vZGVsLnJkYSIpDQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9hbGxfcHJlZGljdGlvbnMucmRhIikNCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19zdXJ2ZXlfZXN0cy5yZGEiKQ0KDQphbGxfcHJlZGljdGlvbnMgJT4lDQogIGdyb3VwX2J5KC5kcmF3KSAlPiUNCiAgc3VtbWFyaXNlKG1lYW5fbjJvID0gbWVhbihuMm8pKSAlPiUNCiAgc3VtbWFyaXNlKGVzdGltYXRlID0gcm91bmQobWVkaWFuKG1lYW5fbjJvKSwgMiksICMgcG9zdGVyaW9yIG1lZGlhbg0KICAgIExDTCA9IHJvdW5kKHF1YW50aWxlKG1lYW5fbjJvLCBwcm9icyA9IDAuMDI1KSwgMiksDQogICAgVUNMID0gcm91bmQocXVhbnRpbGUobWVhbl9uMm8sIHByb2JzID0gMC45NzUpLCAyKSkgJT4lIA0KICBtdXRhdGUodHlwZSA9ICJtb2RlbCIpICU+JQ0KICBiaW5kX3Jvd3MoY2JpbmQobjJvX3N1cnZleV9lc3RzWzEwLCAyOjRdLCB0eXBlID0gcmVwKCJzdXJ2ZXkiLCAxKSkpICU+JQ0KICBtdXRhdGUoY2xfd2lkdGggPSByb3VuZChVQ0wgLSBMQ0wsIDIpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gdHlwZSwgeSA9IGVzdGltYXRlLCBjb2xvciA9IHR5cGUpKSArDQogIGdlb21fcG9pbnQoc2l6ZSA9IDIsIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpICsNCiAgZ2VvbV9saW5lcmFuZ2UoYWVzKHltaW4gPSBMQ0wsIHltYXggPSBVQ0wpICwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSkgKw0KICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoImJsYWNrIiwgImdyZXkiKSkgKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSByb3VuZChtZWFuKGRmX21vZGVsJG4ybyksIDIpLCANCiAgICAgICAgICAgICBsaW5ldHlwZSA9ICJkYXNoZWQiLA0KICAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIikgKw0KICB5bGFiKCJtZWFuIE4yTyBjb25jZW50cmF0aW9uIikgKw0KICBnZ3RpdGxlKCJOYXRpb25hbCBlc3RpbWF0ZSBjb21wYXJpc29uIikgKw0KICBjb29yZF9mbGlwKCkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkNCmBgYA0KDQpCZWxvdywgZXN0aW1hdGVzIHdlcmUgY29tcGFyZWQgYnkgZWNvcmVnaW9uLg0KYGBge3IgbjJvX21lYW5fd3NhOSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2FsbF9wcmVkaWN0aW9ucy5yZGEiKQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX3N1cnZleV9lc3RzLnJkYSIpDQoNCmFsbF9wcmVkaWN0aW9ucyAlPiUNCiAgZ3JvdXBfYnkoV1NBOSwgLmRyYXcpICU+JQ0KICBzdW1tYXJpc2UobWVhbl9uMm8gPSBtZWFuKG4ybykpICU+JQ0KICBncm91cF9ieShXU0E5LCAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgc3VtbWFyaXNlKGVzdGltYXRlID0gcm91bmQobWVkaWFuKG1lYW5fbjJvKSwgMiksDQogICAgTENMID0gcm91bmQocXVhbnRpbGUobWVhbl9uMm8sIHByb2JzID0gMC4wMjUpLCAyKSwNCiAgICBVQ0wgPSByb3VuZChxdWFudGlsZShtZWFuX24ybywgcHJvYnMgPSAwLjk3NSksIDIpLA0KICAgIC5ncm91cHMgPSAiZHJvcCIpICU+JSANCiAgbXV0YXRlKGVjb3JlZ2lvbiA9IGZhY3RvcihXU0E5KSkgJT4lDQogIG11dGF0ZSh0eXBlID0gIm1vZGVsIikgJT4lDQogIHNlbGVjdChlY29yZWdpb24sIGVzdGltYXRlLCBMQ0wsIFVDTCwgdHlwZSkgJT4lDQogIG11dGF0ZShlY29yZWdpb24gPSBmb3JjYXRzOjpmY3RfcmVvcmRlcihlY29yZWdpb24sIGVzdGltYXRlKSkgJT4lDQogIGJpbmRfcm93cyhjYmluZChuMm9fc3VydmV5X2VzdHNbLTEwLF0sIHR5cGUgPSByZXAoInN1cnZleSIsIDkpKSkgJT4lDQogIGFycmFuZ2UoZWNvcmVnaW9uKSAlPiUNCiAgcHJpbnQoKQ0KYGBgDQoNCmBgYHtyIHBsb3RfbWVhbl9uMm9fd3NhOSwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD02LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvYWxsX3ByZWRpY3Rpb25zLnJkYSIpDQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fc3VydmV5X2VzdHMucmRhIikNCg0KYWxsX3ByZWRpY3Rpb25zICU+JQ0KICBncm91cF9ieShXU0E5LCAuZHJhdykgJT4lDQogIHN1bW1hcmlzZShtZWFuX24ybyA9IG1lYW4objJvKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIGdyb3VwX2J5KFdTQTkpICU+JQ0KICBzdW1tYXJpc2UoZXN0aW1hdGUgPSByb3VuZChtZWRpYW4obWVhbl9uMm8pLCAyKSwNCiAgICBMQ0wgPSByb3VuZChxdWFudGlsZShtZWFuX24ybywgcHJvYnMgPSAwLjAyNSksIDIpLA0KICAgIFVDTCA9IHJvdW5kKHF1YW50aWxlKG1lYW5fbjJvLCBwcm9icyA9IDAuOTc1KSwgMiksDQogICAgLmdyb3VwcyA9ICJkcm9wIikgJT4lIA0KICBtdXRhdGUoZWNvcmVnaW9uID0gZmFjdG9yKFdTQTkpKSAlPiUNCiAgbXV0YXRlKHR5cGUgPSAibW9kZWwiKSAlPiUNCiAgc2VsZWN0KGVjb3JlZ2lvbiwgZXN0aW1hdGUsIExDTCwgVUNMLCB0eXBlKSAlPiUNCiAgbXV0YXRlKGVjb3JlZ2lvbiA9IGZvcmNhdHM6OmZjdF9yZW9yZGVyKGVjb3JlZ2lvbiwgZXN0aW1hdGUpKSAlPiUNCiAgYmluZF9yb3dzKGNiaW5kKG4yb19zdXJ2ZXlfZXN0c1stMTAsXSwgdHlwZSA9IHJlcCgic3VydmV5IiwgOSkpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gZWNvcmVnaW9uLCB5ID0gZXN0aW1hdGUsIGdyb3VwID0gdHlwZSwgY29sb3IgPSB0eXBlKSkgKw0KICBnZW9tX3BvaW50KHNpemUgPSAyLCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpKSArDQogIGdlb21fbGluZXJhbmdlKGFlcyh5bWluID0gTENMLCB5bWF4ID0gVUNMKSAsIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpICsNCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCJibGFjayIsICJncmV5IikpICsNCiAgY29vcmRfZmxpcCgpICsgDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgeWxhYigibWVhbiBkaXNzb2x2ZWQgTjJPIikgKw0KICBnZ3RpdGxlKCJFY29yZWdpb24gZXN0aW1hdGVzIGNvbXBhcmlzb24iKQ0KYGBgDQoNCk1lYW5zIHdlcmUgY29tcGFyZWQgYWNjb3JkaW5nIHRvIHNpemUgY2F0ZWdvcmllcyBiZWxvdy4NCmBgYHtyIHRhYmxlX3NpemVfbWVhbl9uMm8sIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NiwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2FsbF9wcmVkaWN0aW9ucy5yZGEiKQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX3N1cnZleV9lc3RzX3NpemUucmRhIikNCg0KYWxsX3ByZWRpY3Rpb25zICU+JQ0KICBncm91cF9ieShzaXplX2NhdCwgLmRyYXcpICU+JQ0KICBzdW1tYXJpc2UobWVhbl9uMm8gPSBtZWFuKG4ybyksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICBncm91cF9ieShzaXplX2NhdCkgJT4lDQogIHN1bW1hcmlzZShlc3RpbWF0ZSA9IHJvdW5kKG1lZGlhbihtZWFuX24ybyksIDEpLA0KICAgIExDTCA9IHJvdW5kKHF1YW50aWxlKG1lYW5fbjJvLCBwcm9icyA9IDAuMDI1KSwgMSksDQogICAgVUNMID0gcm91bmQocXVhbnRpbGUobWVhbl9uMm8sIHByb2JzID0gMC45NzUpLCAxKSwNCiAgICAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgbXV0YXRlKHR5cGUgPSAibW9kZWwiKSAlPiUNCiAgYmluZF9yb3dzKGNiaW5kKG4yb19zdXJ2ZXlfZXN0c19zaXplLCB0eXBlID0gcmVwKCJzdXJ2ZXkiLCA1KSkpICU+JQ0KICBtdXRhdGUoc2l6ZSA9IGZhY3RvcihzaXplX2NhdCkpICU+JQ0KICBtdXRhdGUoc2l6ZSA9IGZvcmNhdHM6OmZjdF9yZW9yZGVyKHNpemUsIGVzdGltYXRlKSkgJT4lDQogIG11dGF0ZShjbF93aWR0aCA9IFVDTCAtIExDTCkgJT4lDQogIGFycmFuZ2Uoc2l6ZSkgJT4lDQogIHNlbGVjdChzaXplLCBlc3RpbWF0ZSwgTENMLCBVQ0wsIHR5cGUpICU+JSANCiAgcHJpbnQoKQ0KYGBgDQoNCmBgYHtyIHBsb3Rfc2l6ZV9tZWFuX24ybywgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD02LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvYWxsX3ByZWRpY3Rpb25zLnJkYSIpDQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fc3VydmV5X2VzdHNfc2l6ZS5yZGEiKQ0KDQphbGxfcHJlZGljdGlvbnMgJT4lDQogIGdyb3VwX2J5KHNpemVfY2F0LCAuZHJhdykgJT4lDQogIHN1bW1hcmlzZShtZWFuX24ybyA9IG1lYW4objJvKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIGdyb3VwX2J5KHNpemVfY2F0KSAlPiUNCiAgc3VtbWFyaXNlKGVzdGltYXRlID0gcm91bmQobWVkaWFuKG1lYW5fbjJvKSwgMiksDQogICAgTENMID0gcm91bmQocXVhbnRpbGUobWVhbl9uMm8sIHByb2JzID0gMC4wMjUpLCAyKSwNCiAgICBVQ0wgPSByb3VuZChxdWFudGlsZShtZWFuX24ybywgcHJvYnMgPSAwLjk3NSksIDIpLA0KICAgIC5ncm91cHMgPSAiZHJvcCIpICU+JSANCiAgI211dGF0ZShzaXplX2NhdCA9IGZhY3RvcihzaXplX2NhdCkpICU+JQ0KICBtdXRhdGUodHlwZSA9ICJtb2RlbCIpICU+JQ0KICBzZWxlY3Qoc2l6ZV9jYXQsIGVzdGltYXRlLCBMQ0wsIFVDTCwgdHlwZSkgJT4lDQogIGJpbmRfcm93cyhjYmluZChuMm9fc3VydmV5X2VzdHNfc2l6ZSwgdHlwZSA9IHJlcCgic3VydmV5IiwgNSkpKSAlPiUNCiAgbXV0YXRlKHNpemVfY2F0ID0gZm9yY2F0czo6ZmN0X3Jlb3JkZXIoc2l6ZV9jYXQsIGVzdGltYXRlKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHNpemVfY2F0LCB5ID0gZXN0aW1hdGUsIGdyb3VwID0gdHlwZSwgY29sb3IgPSB0eXBlKSkgKw0KICBnZW9tX3BvaW50KHNpemUgPSAyLCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpKSArDQogIGdlb21fbGluZXJhbmdlKGFlcyh5bWluID0gTENMLCB5bWF4ID0gVUNMKSAsIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpICsNCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCJibGFjayIsICJncmV5IikpICsNCiAgY29vcmRfZmxpcCgpICsgDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgeWxhYigibWVhbiBkaXNzb2x2ZWQgTjJPIikgKw0KICBnZ3RpdGxlKCJTaXplIGNhdGVnb3J5IGVzdGltYXRlcyBjb21wYXJpc29uIikNCmBgYA0KDQojIyMgU2F0dXJhdGlvbg0KQmVsb3csIHRoZSBzYW1lIGNvbXBhcmlzb25zIHdlcmUgbWFkZSBmb3IgdGhlIHNhdHVyYXRpb24gZXN0aW1hdGVzLg0KYGBge3IgdGFibGVfbmF0X3NhdF9tZWFuLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTh9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZl9tb2RlbC5yZGEiKQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvYWxsX3ByZWRpY3Rpb25zLnJkYSIpDQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9zYXRfc3VydmV5X2VzdHMucmRhIikNCg0KYWxsX3ByZWRpY3Rpb25zICU+JQ0KICBncm91cF9ieSguZHJhdykgJT4lDQogIHN1bW1hcmlzZShtZWFuX3NhdCA9IG1lYW4objJvc2F0KSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIHN1bW1hcmlzZShlc3RpbWF0ZSA9IHJvdW5kKG1lZGlhbihtZWFuX3NhdCksIDMpLA0KICAgIExDTCA9IHJvdW5kKHF1YW50aWxlKG1lYW5fc2F0LCBwcm9icyA9IDAuMDI1KSwgMyksDQogICAgVUNMID0gcm91bmQocXVhbnRpbGUobWVhbl9zYXQsIHByb2JzID0gMC45NzUpLCAzKSwNCiAgICAuZ3JvdXBzID0gImRyb3AiKSAlPiUgDQogIG11dGF0ZSh0eXBlID0gIm1vZGVsIikgJT4lDQogIGJpbmRfcm93cyhjYmluZChzYXRfc3VydmV5X2VzdHNbMTAsIDI6NF0sIHR5cGUgPSByZXAoInN1cnZleSIsIDEpKSkgJT4lDQogIGFkZF9yb3coZXN0aW1hdGUgPSByb3VuZChtZWFuKGRmX21vZGVsJG4ybyAvIGRmX21vZGVsJG4yb19lcSksIDMpLA0KICAgICAgICAgIHR5cGUgPSAic2FtcGxlIikgJT4lDQogIHByaW50KCkNCmBgYA0KDQpgYGB7ciBwbG90X25hdF9zYXRfbWVhbiwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTIsIGZpZy53aWR0aD00LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvZGZfbW9kZWwucmRhIikNCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2FsbF9wcmVkaWN0aW9ucy5yZGEiKQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvc2F0X3N1cnZleV9lc3RzLnJkYSIpDQoNCmFsbF9wcmVkaWN0aW9ucyAlPiUNCiAgZ3JvdXBfYnkoLmRyYXcpICU+JQ0KICBzdW1tYXJpc2UobWVhbl9zYXQgPSBtZWFuKG4yb3NhdCkpICU+JQ0KICBzdW1tYXJpc2UoZXN0aW1hdGUgPSByb3VuZChtZWRpYW4obWVhbl9zYXQpLCAzKSwNCiAgICBMQ0wgPSByb3VuZChxdWFudGlsZShtZWFuX3NhdCwgcHJvYnMgPSAwLjAyNSksIDMpLA0KICAgIFVDTCA9IHJvdW5kKHF1YW50aWxlKG1lYW5fc2F0LCBwcm9icyA9IDAuOTc1KSwgMykpICU+JSAgDQogIG11dGF0ZSh0eXBlID0gIm1vZGVsIikgJT4lDQogIGJpbmRfcm93cyhjYmluZChzYXRfc3VydmV5X2VzdHNbMTAsIDI6NF0sIHR5cGUgPSByZXAoInN1cnZleSIsIDEpKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHR5cGUsIHkgPSBlc3RpbWF0ZSwgY29sb3IgPSB0eXBlKSkgKw0KICBnZW9tX3BvaW50KHNpemUgPSAyLCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpKSArDQogIGdlb21fbGluZXJhbmdlKGFlcyh5bWluID0gTENMLCB5bWF4ID0gVUNMKSAsIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpICsNCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCJibGFjayIsICJncmV5IikpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gcm91bmQobWVhbihkZl9tb2RlbCRuMm8gLyBkZl9tb2RlbCRuMm9fZXEpLCAzKSwgDQogICAgICAgICAgICAgbGluZXR5cGUgPSAiZGFzaGVkIiwNCiAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIpICsNCiAgeWxhYigibWVhbiBOMk8gc2F0dXJhdGlvbiByYXRpbyIpICsNCiAgZ2d0aXRsZSgiTmF0aW9uYWwgZXN0aW1hdGVzIGNvbXBhcmlzb24iKSArDQogIGNvb3JkX2ZsaXAoKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KYGBgDQpgYGB7ciBwbG90X3dzYTlfc2F0X21lYW4sIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NiwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2FsbF9wcmVkaWN0aW9ucy5yZGEiKQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvc2F0X3N1cnZleV9lc3RzLnJkYSIpDQoNCmFsbF9wcmVkaWN0aW9ucyAlPiUNCiAgZ3JvdXBfYnkoV1NBOSwgLmRyYXcpICU+JQ0KICBzdW1tYXJpc2UoIG1lYW5fc2F0ID0gbWVhbihuMm9zYXQpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgZ3JvdXBfYnkoV1NBOSkgJT4lDQogIHN1bW1hcmlzZSggZXN0aW1hdGUgPSByb3VuZChtZWRpYW4obWVhbl9zYXQpLCAzKSwNCiAgICBMQ0wgPSByb3VuZChxdWFudGlsZShtZWFuX3NhdCwgcHJvYnMgPSAwLjAyNSksIDMpLA0KICAgIFVDTCA9IHJvdW5kKHF1YW50aWxlKG1lYW5fc2F0LCBwcm9icyA9IDAuOTc1KSwgMyksDQogICAgLmdyb3VwcyA9ICJkcm9wIikgJT4lIA0KICBtdXRhdGUoZWNvcmVnaW9uID0gZmFjdG9yKFdTQTkpKSAlPiUNCiAgbXV0YXRlKHR5cGUgPSAibW9kZWwiKSAlPiUNCiAgbXV0YXRlKGVjb3JlZ2lvbiA9IGZvcmNhdHM6OmZjdF9yZW9yZGVyKGVjb3JlZ2lvbiwgZXN0aW1hdGUpKSAlPiUNCiAgc2VsZWN0KGVjb3JlZ2lvbiwgZXN0aW1hdGUsIExDTCwgVUNMLCB0eXBlKSAlPiUNCiAgYmluZF9yb3dzKGNiaW5kKHNhdF9zdXJ2ZXlfZXN0c1stMTAsXSwgdHlwZSA9IHJlcCgic3VydmV5IiwgOSkpKSAlPiUNCiAgbXV0YXRlKGNsX3dpZHRoID0gVUNMIC0gTENMKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gZWNvcmVnaW9uLCB5ID0gZXN0aW1hdGUsIGdyb3VwID0gdHlwZSwgY29sb3IgPSB0eXBlKSkgKw0KICBnZW9tX3BvaW50KHNpemUgPSAyLCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpKSArDQogIGdlb21fbGluZXJhbmdlKGFlcyh5bWluID0gTENMLCB5bWF4ID0gVUNMKSAsIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpICsNCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCJibGFjayIsICJncmV5IikpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMSwgY29sb3IgPSAibGlnaHRncmV5IikgKw0KICB5bGFiKCJtZWFuIE4yTyBzYXR1cmF0aW9uIHJhdGlvIikgKw0KICBnZ3RpdGxlKCJFY29yZWdpb24gZXN0aW1hdGVzIGNvbXBhcmlzb24iKSArDQogIGNvb3JkX2ZsaXAoKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KYGBgDQoNCmBgYHtyIHRhYmxlX3NpemVfc2F0X21lYW4sIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NiwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2FsbF9wcmVkaWN0aW9ucy5yZGEiKQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvc2F0X3N1cnZleV9lc3RzX3NpemUucmRhIikNCg0KYWxsX3ByZWRpY3Rpb25zICU+JQ0KICBncm91cF9ieShzaXplX2NhdCwgLmRyYXcpICU+JQ0KICBzdW1tYXJpc2UobWVhbl9zYXQgPSBtZWFuKG4yb3NhdCksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICBncm91cF9ieShzaXplX2NhdCkgJT4lDQogIHN1bW1hcmlzZShlc3RpbWF0ZSA9IHJvdW5kKG1lZGlhbihtZWFuX3NhdCksIDMpLA0KICAgIExDTCA9IHJvdW5kKHF1YW50aWxlKG1lYW5fc2F0LCBwcm9icyA9IDAuMDI1KSwgMyksDQogICAgVUNMID0gcm91bmQocXVhbnRpbGUobWVhbl9zYXQsIHByb2JzID0gMC45NzUpLCAzKSkgJT4lDQogIG11dGF0ZSh0eXBlID0gIm1vZGVsIikgJT4lDQogIGJpbmRfcm93cyhjYmluZChzYXRfc3VydmV5X2VzdHNfc2l6ZSwgdHlwZSA9IHJlcCgic3VydmV5IiwgNSkpKSAlPiUNCiAgbXV0YXRlKHNpemUgPSBmYWN0b3Ioc2l6ZV9jYXQpKSAlPiUNCiAgbXV0YXRlKGNsX3dpZHRoID0gVUNMIC0gTENMKSAlPiUNCiAgYXJyYW5nZShzaXplKSAlPiUNCiAgc2VsZWN0KHNpemUsIGVzdGltYXRlLCBMQ0wsIFVDTCwgdHlwZSkgJT4lIA0KICBwcmludCgpDQpgYGANCg0KYGBge3IgcGxvdF9zaXplX3NhdF9tZWFuLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTYsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9hbGxfcHJlZGljdGlvbnMucmRhIikNCg0KYWxsX3ByZWRpY3Rpb25zICU+JQ0KICBncm91cF9ieShzaXplX2NhdCwgLmRyYXcpICU+JQ0KICBzdW1tYXJpc2UobWVhbl9zYXQgPSBtZWFuKG4yb3NhdCksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICBncm91cF9ieShzaXplX2NhdCkgJT4lDQogIHN1bW1hcmlzZShlc3RpbWF0ZSA9IHJvdW5kKG1lZGlhbihtZWFuX3NhdCksIDMpLA0KICAgIExDTCA9IHJvdW5kKHF1YW50aWxlKG1lYW5fc2F0LCBwcm9icyA9IDAuMDI1KSwgMyksDQogICAgVUNMID0gcm91bmQocXVhbnRpbGUobWVhbl9zYXQsIHByb2JzID0gMC45NzUpLCAzKSwNCiAgICAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgbXV0YXRlKHR5cGUgPSAibW9kZWwiKSAlPiUNCiAgYmluZF9yb3dzKGNiaW5kKHNhdF9zdXJ2ZXlfZXN0c19zaXplLCB0eXBlID0gcmVwKCJzdXJ2ZXkiLCA1KSkpICU+JQ0KICBtdXRhdGUoc2l6ZSA9IGZhY3RvcihzaXplX2NhdCkpICU+JQ0KICBzZWxlY3Qoc2l6ZSwgZXN0aW1hdGUsIExDTCwgVUNMLCB0eXBlKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHNpemUsIHkgPSBlc3RpbWF0ZSwgZ3JvdXAgPSB0eXBlLCBjb2xvciA9IHR5cGUpKSArDQogIGdlb21fcG9pbnQocG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSkgKw0KICBnZW9tX2xpbmVyYW5nZShhZXMoeW1pbiA9IExDTCwgeW1heCA9IFVDTCkgLCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpKSArDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygiYmxhY2siLCAiZ3JleSIpKSArDQogIHlsYWIoIm1lYW4gTjJPIHNhdHVyYXRpb24gcmF0aW8iKSArDQogIGdndGl0bGUoIlNpemUgY2F0ZWdvcnkgZXN0aW1hdGVzIGNvbXBhcmlzb24iKSArDQogIGNvb3JkX2ZsaXAoKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KYGBgDQoNCiMgUmVmZXJlbmNlcw0KDQojIFNlc3Npb24gSW5mbw0KYGBge3Igc2Vzc2lvbn0NCnNlc3Npb25JbmZvKCkNCmBgYA==